https://kotlinlang.org logo
Title
i

Ihar S

03/13/2021, 9:39 PM
Hello Kotest magicians, I'm looking into the Kotest and trying to understand the best practices The Groovy Spock is the main testing framework for me at the moment, and I like it a lot. However, the groovy dependencies generate an unreasonable level of discomfort in my kotlin projects. Therefore I'm looking for a replacement and Kotest looks awesome and super promising. But I can find good examples for Data Driver Testing with Kotest. https://spockframework.org/spock/docs/1.0/data_driven_testing.html My perfect scenario will be the next one: • Keep the usage of
Given When Then
- it is covered by
BehaviorSpec
• Usage of something similar to
Data Tables
from Spock but in Kotest -
io.kotest.data.forAll
looks similar Can anyone please point me to any well written example? Because I end-up with a
callback hell
all the time Thank you in advance!
s

sam

03/13/2021, 10:39 PM
Do you have an example of what you have at the moment
i

Ihar S

03/14/2021, 7:13 PM
Of course! Unfortunately I had to remove meaningful parts of the test body, however, the skeleton is the same
class SomeDataTest : BehaviorSpec({

    Given("...") {
        When("...") {
            forAll(
                table(
                    headers("frontPageKey", "pageUrl", "expected result"),
                    row(null, null, null),
                    row("key", "key", "something"),
                    row(null, "something", null),
                )
            ) { key1: String?, key2: String?, expectedResult: String? ->
                Then("...") {
                    
                }
            }
        }
    }
})
s

sam

03/14/2021, 8:51 PM
Ok, that looks right. And what is the issue exactly - that you think it's a bit verbose ?
d

dave08

03/15/2021, 3:02 AM
I think he means it's too much nesting, contrary to the linear get when then in spock
s

sam

03/15/2021, 3:05 AM
Ah I see. Well you don't have to use behavior spec, can use fun spec, and with the latest data driving stuff in 4.4 you don't even need to have any nesting at all.
d

dave08

03/15/2021, 3:06 AM
I've seen some libs that tried given("") { }.when("") { }.then("") { } kind of style with less nesting, but I'm not sure it would be possible in kotest
Fun spec is also nested in contexts
The idea is that given and when need to be registered as the then parent even though they are on the same nesting level...
(Considering the
and
along the way... which makes that harder since when can also have it...)
i

Ihar S

03/15/2021, 9:12 AM
@dave08 yes, you pointed the main problem here. The BehaviorSpec has over too much nesting level especially with additional `And`(s)
d

dave08

03/15/2021, 9:17 AM
The truth is, that if the main thing you need to identify the test is
"maximum of two numbers"
, then you could just do:
init {
   test("maximum of two numbers") {
       // given -- maybe the table here?

       // when -- run the SUT

       // use the forAll
    }
}
with those comments there to delimit the sections, but then it just boils down to JUnit with an additional bell-and-whistle of forAll...
The fact is that groovy just allows too much flexibility sometimes -- Kotlin limits that in a way that makes code clearer as to how it works -- with the cost of this kind of functionality being hard to implement.
That said, Minutest's v2 (currently beta https://github.com/dmcg/minutest/tree/v2#moving-from-junit-to-minutest) is trying to improve this by separating the fixture into a
given()
section that isn't nested, and you can use that there. But it's missing tons of features that Kotest has, and the devotion that's dedicated to it ❤️... the devs really go out of their way to help out in Kotest!
❤️ 1
i

Ihar S

03/15/2021, 10:04 AM
Thank you for your suggestions @dave08, I will try to play a bit more with Kotest in the minor projects, however unfortunately I feel Spock will remain a company-wise standard