-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
runBlockingTest doesn't cancel child coroutines when an assertion or exception fails the test #1910
Comments
I'll add that this behaviour is not consistent with that of runBlocking. The example below is probably redundant, given the excellent example provided by the OP, other than to show the test that uses runBlocking passes, while runBlockingTest causes this to fail. coroutines v1.3.7
|
Right now I am using a try / finally to stop the coroutine after assertion failed. I tried using assertFailsWith but doesn't seem like it's implemented yet? Have you found a solution on this? @mrf7 |
This bug does affect all kind of exceptions. I throw an IllegalStateException and the coroutine das not stop. It feels like the delay has no affect and that the coroutine has no chance to react.
|
It's been a long time since I raised this so I dont remember for sure but I don't think I found a real solution to it. If I remember right I just made some workaround that either avoids launching the coroutine in the test or manually cleans up the coroutine before failing the test. |
I've also stumbled upon this. runBlockingTest {
launch {
error("Fail.")
}
delay(1_000) // expected: IllegalStateException: Fail.
Mutex(locked = true).lock() // actual: IllegalStateException: This job has not completed yet
} Makes it hard to find the root cause of such errors in more complex scenarios. |
I also encountered this issue yesterday. Spent a lot of hours narrowing down to this root cause. Turns out my business logic has a custom implementation of the throttle operation that uses a while & delay combo similar to below: @Test
fun test() = runBlockingTest {
launch {
while (isActive) {
delay(1000)
}
}
} I'm thinking that, maybe I'm using coroutine v1.4.2 & kotlin v1.4.30. |
I also find this behaviour unexpected. This is due to the fact that the test scope created by A very easy way to workaround it is to use Are there any plans to fix it in the library? Or is this scope lacking a |
This commit introduces the new version of the test module. Please see README.md and MIGRATION.md for a thorough discussion of the changes. Fixes Kotlin#1203 Fixes Kotlin#1609 Fixes Kotlin#2379 Fixes Kotlin#1749 Fixes Kotlin#1204 Fixes Kotlin#1390 Fixes Kotlin#1222 Fixes Kotlin#1395 Fixes Kotlin#1881 Fixes Kotlin#1910 Fixes Kotlin#1772 Fixes Kotlin#1626 Fixes Kotlin#1742 Fixes Kotlin#2082 Fixes Kotlin#2102 Fixes Kotlin#2405 Fixes Kotlin#2462 Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
This commit introduces the new version of the test module. Please see README.md and MIGRATION.md for a thorough discussion of the changes. Fixes Kotlin#1203 Fixes Kotlin#1609 Fixes Kotlin#2379 Fixes Kotlin#1749 Fixes Kotlin#1204 Fixes Kotlin#1390 Fixes Kotlin#1222 Fixes Kotlin#1395 Fixes Kotlin#1881 Fixes Kotlin#1910 Fixes Kotlin#1772 Fixes Kotlin#1626 Fixes Kotlin#1742 Fixes Kotlin#2082 Fixes Kotlin#2102 Fixes Kotlin#2405 Fixes Kotlin#2462 Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
If an assertion fails in a unit test, coroutines started using the scope of runBlockingTest do not get cancelled and can end up making the test hang forever.
This test never completes because the job inside launch isn't cancelled when Assert.fail() cancels the job running the test.
This also applies to functions that launch coroutines on a scope passed as a parameter.
Explicitly using cancel, however does properly cancel the TestCoroutineScope as well as all of its children
The text was updated successfully, but these errors were encountered: