https://kotlinlang.org logo
Title
d

Dias

02/20/2020, 11:06 AM
as in the rest why asserAll/forAll are not suspend functions?
w

wasyl

02/20/2020, 11:07 AM
There is a
forall
variant in
suspend
package, so maybe you’re importing wrong version?
io.kotlintest.data.suspend.forall
s

simon.vergauwen

02/20/2020, 11:07 AM
Why separate them?
🤷‍♂️ 1
Good to know, first I heard about this as a long time KotlinTest user 😄
d

Dias

02/20/2020, 11:15 AM
that's for data driven test right?
I need generators tho
s

simon.vergauwen

02/20/2020, 11:54 AM
forAll(<http://Gen.int|Gen.int>(), Gen.string()) { int, string ->
   ...
}
I do property-based testing with
forAll
d

Dias

02/20/2020, 12:53 PM
which is not suspendable
s

sam

02/20/2020, 2:20 PM
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

AJ Alt

02/22/2020, 12:05 AM
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

sam

02/22/2020, 12:16 AM
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

simon.vergauwen

02/22/2020, 11:40 AM
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

sam

02/23/2020, 10:04 PM
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

simon.vergauwen

02/24/2020, 8:38 AM
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

AJ Alt

02/24/2020, 5:21 PM
It looks like ultimately all these suspend functions get called with
runBlocking
in the KotestEngine. What if we changed to
forall
to work like
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

simon.vergauwen

02/24/2020, 5:22 PM
That would hinder accumulating them and running them in parallel, no?
s

sam

02/24/2020, 5:37 PM
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

simon.vergauwen

02/24/2020, 5:39 PM
I guess if we allocated each test a separate thread from Dispatchers.IO then it wouldn’t really matter.
That sounds dangerous