https://kotlinlang.org logo
#kotest
Title
# kotest
b

bbaldino

12/16/2020, 11:09 PM
I'm running into an issue where I'm using
runBlockingTest
and
advanceUntilIdle
and I think it's fooling kotest into thinking the test has timed out
kotest complains about
Test did not complete within 600000ms
, but I watch the test and know it didn't sit for a minute
I'm using
runBlockingTest
within the top
context
block, maybe that's wrong. Trying to repro with a small example, maybe I'm doing something dumb.
s

Shalom Halbert

12/16/2020, 11:15 PM
Can you share a code sample?
b

bbaldino

12/16/2020, 11:16 PM
Yeah, trying to get something together.
Ok, I think this shows what I'm seeing
Copy code
class FooTest : ShouldSpec({
    context("top") {
        runBlockingTest {
            context("middle") {
                context("bottom") {
                    launch {
                        delay(Long.MAX_VALUE)
                        latch.countDown()
                    }
                    advanceUntilIdle()
                    should("something") {
                        latch.count shouldBe 0
                    }
                }
            }
        }
    }
})
That will fail instantly, complaining
Test did not complete within 600000ms
I'm guessing because the fake clock of
runBlockingTest
gets used at some point by kotest to check for timeout
s

Shalom Halbert

12/16/2020, 11:35 PM
Is it possible that the amount of time is an issue? If you make the
delay
590000, doe the issue persist? You could be impacted by the the
advanceUntilIdle
In which case, you'd need to increase the test's timeout period
b

bbaldino

12/16/2020, 11:35 PM
Yeah that's what I'm guessing it is
Hm, even if I make the delay
30000
, I see the same thing
Ah, it's probably because the
withTimeout
is effectively done within
runBlockingTest
, so
advanceUntilIdle
goes until that finishes as well
If I move
runBlockingTest
to within the "bottom"
context
, it's fine
That won't work so well with my real test, but, at least that probably explains what's happening
✔️ 1
s

sam

12/16/2020, 11:48 PM
what does run blocking test do ?
b

bbaldino

12/16/2020, 11:48 PM
Is part of kotlinx-coroutines-test
s

sam

12/16/2020, 11:48 PM
is that what provides advance til idle
so you can test delays ?
b

bbaldino

12/16/2020, 11:48 PM
It's basically a helper for testing coroutine code more deterministically
Yeah
s

sam

12/16/2020, 11:48 PM
interesting
b

bbaldino

12/16/2020, 11:49 PM
I was thinking of working around this by rewriting the test to avoid the nesting and just doing isolated test cases.
But where does the
withTimeout
get applied for a test case?
s

sam

12/16/2020, 11:49 PM
it gets added every time a test block starts
b

bbaldino

12/16/2020, 11:49 PM
Whatever adds the
withTimeout
would have to be outside
runBlockingTest
I think
Where 'test block' is defined as what? A
should
in this case?
s

sam

12/16/2020, 11:50 PM
so withtimeout is added by the TestExecutor class in kotest, before user code is invoked
yep, any kotest lambda block
it will add a withTimeout at every level
b

bbaldino

12/16/2020, 11:50 PM
Hm
It works with
runBlockingTest
wrapping a
should
block ok.
s

sam

12/16/2020, 11:50 PM
so you might have more success in this case by using a flat structure, dropping the context
b

bbaldino

12/16/2020, 11:50 PM
So maybe it's that it can't be outside a
context
Yeah, looks like it
s

sam

12/16/2020, 11:57 PM
it might be that the withTimeout runs and then there's another withTimeout for the nested scope
b

bbaldino

12/16/2020, 11:57 PM
Yeah, some
withTimeout
must be run within the
runBlockingTest
, so it becomes a child of that scope, so then
advanceUntilIdle
advances until that finishes as well I think
s

sam

12/16/2020, 11:58 PM
yep because you're putting the test coroutine context outside of context, so that's why
6 Views