I'm running into an issue where I'm using `runBloc...
# kotest
b
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
Can you share a code sample?
b
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
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
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
what does run blocking test do ?
b
Is part of kotlinx-coroutines-test
s
is that what provides advance til idle
so you can test delays ?
b
It's basically a helper for testing coroutine code more deterministically
Yeah
s
interesting
b
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
it gets added every time a test block starts
b
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
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
Hm
It works with
runBlockingTest
wrapping a
should
block ok.
s
so you might have more success in this case by using a flat structure, dropping the context
b
So maybe it's that it can't be outside a
context
Yeah, looks like it
s
it might be that the withTimeout runs and then there's another withTimeout for the nested scope
b
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
yep because you're putting the test coroutine context outside of context, so that's why