You should use structured concurrency so exceptions bubble up the right scope, so passing the test scope was a good idea. Regarding the hanging problem, instead of passing the test scope directly, you could use
backgroundScope if you need long-running coroutines that should be canceled at the end of the test.
Also, I think the new version of
runTest
actually fails on uncaught exceptions by default now (coroutines 1.7.0).