-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add a a way to disable automatic delay skipping with runBlockingTest #1266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think |
Plus, |
I'm not sure what you are trying to achieve. What is your use-case? What kind of test are you trying to write? |
Let's say I have simple method like that: fun CoroutineScope.showAnimationForTwoSeconds() = launch {
animationController.startAnimation()
delay(2000)
animationController.stopAnimation()
} Then I want to properly test this: fun testAnimationStart() = runBlockingTest {
showAnimationForTwoSeconds()
assertThat(animationController).isAnimationRunning()
advanceTimeBy(2000)
assertThat(animationController).isAnimationNotRunning()
} At the moment this test would fail since |
I just noticed that documentation states that manually launched coroutines should not auto-advance delays. However, this does not appear to be the case. Copy pasting that example code from |
What about using Or, call |
That works, but:
|
True... |
cc @objcode |
Ahoy! Thanks for the issue let me take a look into this and make a longer reply. Cheers, |
Ok had time to look into this more - I wanted to write some tests and check on behaviors before posting a reply to ensure that there were no bugs uncovered here. Auto-advancing after test completionTo start with, most of the issues raised above arise from confusion about exactly when
Should you fork
|
Thanks for the writeup. I've done some testing and I've managed to isolate I've been facing in this code sample, which is a modification of your test above. @Test(timeout = 1_000)
fun testAdvancement() {
fun CoroutineScope.startAsync() = rxFlowable {
while (isActive) {
delay(10_000)
println("Delay skipped...")
send(Unit)
}
}
runBlockingTest {
val subscriber = startAsync().test()
subscriber.assertValueCount(1)
subscriber.dispose()
}
} with For me, above test will for some reason start skipping all delays at Weirldy enough, |
That is unexpected. Thanks for the repro! Let me take a look to see if I can figure out what's going on. |
…execution and delay, do not skip delays with runBlockingTest{} Kotlin/kotlinx.coroutines#1266
I've managed to shorten my repro case significantly and only using coroutines this time (no rx): @Test
fun testAdvancement() {
runBlockingTest {
val extraJob = launch {
while (isActive) {
delay(1_000)
}
}
// Perform some assertion (just true in this case to simplify).
// If assertion fails, test will start looping infinitely
if (true) {
throw AssertionError()
}
extraJob.cancel()
}
} Workaround is to put |
Looks like this issue is an instance of #1910. |
You are correct. Closing this as duplicate. |
In many cases it would be useful to accurately control time within tests (for example when testing time-based coroutine logic). However, at the moment
runBlockingTest
seems to enforce delay-skipping behavior.There does not seem to be a good alternative to this method at the moment if I don't want delay skipping. I can manually create
TestCoroutineScope
but that takes some boilerplate and does not bring all the benefits ofrunBlockingTest
(such as making sure all launched tasks have been properly stopped).At the moment I'm using copy paste version of
runBlockingTest
withdispatcher.advanceUntilIdle()
removed, but that is really bad solution.The text was updated successfully, but these errors were encountered: