As nested tests on K/JS are not possible is there ...
# kotest
v
As nested tests on K/JS are not possible is there some other way to call a suspending function outside the inner-most lambda? For example I need to call
withData
with an argument that is the result of a suspending call (
readdir
).
l
For this one I'm not really knowledgeable in Kotlin JS, but let me try. One suggestion is to use suspending test factories, they might fit the need of nested tests as a gambiarra
I believe calling suspending functions should still work in JS, as the tests should inherit the coroutines and allow you to call the methods Could you give a small sample?
v
Sure, the example would be
Copy code
class SchemaTest : FunSpec({
    beforeSpec {
        validate = Ajv(Options(strict = true)).compile(
            JSON.parse(readFile(schemaFile, utf8))
        )
    }

    withData(readdir(dataDir).asIterable()) {
        readFile(path.join(dataDir, it), utf8) should beValid()
    }
})

lateinit var validate: ValidateFunction

fun beValid(): Matcher<String> {
    return Matcher { data ->
        MatcherResult(
            validate(YAML.parse(data)),
            { "..." },
            { "..." },
        )
    }
}
Where
readdir
is the "problematic" call that is not working as not in a suspending context. Wrapping the
withData(...) { ... }
into
context("foo") { ... }
compiles as now the
readdir
is done in the suspending context, but it fails at runtime as nested tests are not supported on JS due to https://github.com/kotest/kotest/issues/3141.
Do you have a reference to "suspending test factories"?
Found https://kotest.io/docs/framework/test-factories.html, but the
funSpec(...)
function also is not suspending so would have the same problem, wouldn't it?
So taking a step back, what I want is to generate several test cases from the result of a suspending function. Whether this is via
withData
or something else, I don't care too much. But it has to work for K/JS, so cannot use nested tests currently.
Anyone? :-)
e
Not ideal, but is it an option to wrap the suspending call in
runBlocking
?
I haven't worked enough with JS-targets to have any ready solutions ๐Ÿ˜•
v
Exception during run: IllegalStateException: runBlocking is not available on JS
๐Ÿ˜ž
o
Given the current Kotest architecture, you cannot have a suspending function outside of a leaf test on JS. The JS test infra which Kotest uses via KGP supports async calls only on leaf tests. I'm not sure whether you might get away with invoking the suspending setup function in the first leaf test, then reusing its results in subsequent tests.
c
https://opensavvy.gitlab.io/groundwork/prepared/docs/ emulates nested tests on Kotlin/JS on top of Kotest (you write your tests as nested, but during execution and in test reports they are flattened)
v
I'm not sure whether you might get away with invoking the suspending setup function in the first leaf test, then reusing its results in subsequent tests.
That wouldn't help here. I do that with
beforeSpec
already where I do a suspending call to read a file that I then later use in the tests. But I want to generate test cases from the result of the suspending call here.
Thanks @CLOVIS, I'll give that a try
Do you have a link how to get started? On their docs I don't even quickly find coordinates, let alone how to get it started.
o
> But I want to generate test cases from the result of the suspending call here. I cannot see how that would be possible in any test framework using the KGP test infra: The JS test frameworks (Mocha primarily) expect tests to be registered via blocking
suite
invocations.
c
If you have any questions about Prepared, the dedicated channel is #C078Z1QRHL3 The getting started page is https://opensavvy.gitlab.io/groundwork/prepared/docs/tutorials/index.html, feel free to send a message if you think some parts of it can be improved
v
Yeah, that page does not at all tell how to use Prepared or even under which coordinates it lives. Found it now. A bit nervous as it is in Alpha-state though. ๐Ÿ˜•
c
2.0.0 is in alpha state. The previous 1.x.x is stable, and all breaking changes in 2.0.0 are minimal (almost only deprecated stuff) โ†’ https://gitlab.com/opensavvy/groundwork/prepared/-/milestones/3#tab-issues
v
Ah, sorry, was on the wrong artifact, there only v2 was available
c
but yeah if you use Kotest you should use
:runner-kotest
and possibly
:compat-parameterize
, with the setup being described here: https://opensavvy.gitlab.io/groundwork/prepared/api-docs/runners/runner-kotest/index.html
v
Hm, same problem? The argument to
suite
is not suspending so I cannot do the
readdir
call
c
Shared suspending operations are wrapped in
prepared {}
: https://opensavvy.gitlab.io/groundwork/prepared/docs/features/prepared-values.html
o
But you cannot dynamically generate tests from a
prepared
lambda, right?
c
sorry, in a meeting rn, brb
but I'm pretty sure you can do what you want
v
No luck yet, maybe you have some more insights after the meeting ๐Ÿ™‚
c
Moving the Prepared-related discussion to https://kotlinlang.slack.com/archives/C078Z1QRHL3/p1736875209796099?thread_ts=1736875209.796099&amp;cid=C078Z1QRHL3 so the Kotest team can keep this thread to discuss their library
v
Well, it is my thread and it seems the pure kotest outcome was that it is not possible, that's why I did not layout the discussion as imho it is still the topic of my thread, but sure, will update here with the result then later. ๐Ÿ™‚
Oh my god, I am an idiot. I just have to use
readdirSync
instead of
readdir
as that is not suspending but blocking. The general question is still interesting on whether it can be solved, but my use-case is solved with that. ๐Ÿ™ˆ