as in the rest why asserAll/forAll are not suspend...
# kotest
d
as in the rest why asserAll/forAll are not suspend functions?
w
There is a
forall
variant in
suspend
package, so maybe you’re importing wrong version?
io.kotlintest.data.suspend.forall
s
Why separate them?
🤷‍♂️ 1
Good to know, first I heard about this as a long time KotlinTest user 😄
d
that's for data driven test right?
I need generators tho
s
Copy code
forAll(<http://Gen.int|Gen.int>(), Gen.string()) { int, string ->
   ...
}
I do property-based testing with
forAll
d
which is not suspendable
s
They were not suspendable because they existed before coroutines did and we couldn't just change it after. But in 4.0 because it's a major change they have become suspendable
So tldr wait for 4.0 or try the beta :)
👍 1
a
Although I understand the elegance of making all the table tasting functions
suspend
, that change means they can't be used in non-suspending contexts. Some large teams at Microsoft make extensive use of
forall
with a JUnit test runner.
4.0.0-BETA1
is unusable for them. I think we should either make
forAll
non-suspending, but take a suspending lambda, or continue to provide both suspending and non-suspending versions of the functions.
s
You can't take a suspend lamba and run it in a non suspend function I don't think
Let me think about what we can do. Maybe inlining is a solution
Maybe just duplicating them like before is the solution
s
You can’t take a suspend lamba and run it in a non suspend function I don’t think
You can if you implement a basic runtime for
suspend
like Arrow Fx and KotlinX do. Or you need to wrap in
IO
or
Deferred
so you can delay executing the
suspend
from a non-suspend function.
I.e. if
forAll
becomes a DSL a nested DSL of
TestCase
, that way your
suspend
is wrapped in
TestCase
and you can run them yourself later however you want
Wouldn’t something like that work?
Sounds like a very interessing design challenge 😬
s
I think the problem is it needs to work outside of KotlinTest/kotest. That's why having the suspend is a problem as junit doesn't understand it,
s
Yes, but that is why building your own
suspend
runner would solve your problem. Which is quite easy to do.
You can make
Junit
understand with an adaption layer that has a
suspend
runner, no?
Whenever interpreting
TestCase
into junit
a
It looks like ultimately all these suspend functions get called with
runBlocking
in the KotestEngine. What if we changed to
forall
to work like
Copy code
fun forAll(vararg rows: Row, testfn: suspend (...) -> Unit) = runBlocking {...}
That would allow you to pass in suspend functions, but call
forAll
from a blocking context. The behavior would stay the same as it is right now.
s
That would hinder accumulating them and running them in parallel, no?
s
It would stop the thread that’s being used yeah. I guess if we allocated each test a separate thread from Dispatchers.IO then it wouldn’t really matter.
We already allocate a thread per Spec actually (or at least share threads were parallelism is used).
I guess the downside is if you want to use a coroutine inside forAll and suspend, while running something outside of it, in the same test scope. But what are the chances of that.
s
I guess if we allocated each test a separate thread from Dispatchers.IO then it wouldn’t really matter.
That sounds dangerous