Arrow Matchers

New in Kotest 3.1.0 was the addition of a brilliant new add on module for arrow. If you’re new to arrow then it’s a set of datatypes, type classes and more that really help when writing code in a functional style. Kotest itself uses arrow for things like error handling.

Add the kotest-assertions-arrow module to your build and then you’ll need a raft of new assertions (matchers) available that can be used with the datatypes provided by Arrow.

For example, if we have a function that parses a string and returns either an Int or a Double depending on the input, we can use the Either assertions.

class EitherExample : StringSpec({



fun parse(string:String): Either<Int, Double> = ...



"parse should detect an integer" {

parse("1").shouldBeLeft(1)

}



"parse should detect a double" {

parse("2.3").shouldBeRight(2.3)

}

})

Another example is the non-empty-list datatype. This allows code to statically provide a list that is guaranteed to contain at least one element. Testing against this requires custom matchers as it is not part of the regular collections library.

class NelExample : StringSpec({



fun emails(): NonEmptyList<String> = ...



"emails should contain no nulls" {

emails().shouldNotContainNull()

}



"emails should be unique" {

emails().shouldBeUnique()

}

})

There are other assertions available — for the Validation, Option, and Try datatypes as well as for Either and NonEmptyList shown here.

Focusing Tests

Sometimes we want to temporarily disable some tests in of a test suite. Perhaps we’re experimenting with some API changes and don’t want to have to keep changing all the tests until we’re happy with the new API. Or perhaps we’re debugging and want to reduce the noise in the output.

Whatever the reason, Kotest supports selectively running a single top level test by preceding the test name with “f:”. Then only that test (and subtests of it) will be executed.

For example, in the following snippet only the middle test will be executed.

class FocusExampleTest : StringSpec({



"this will be ignored" {

// test here

}



"f:this is not ignored as it is focused" {

// test here

}



"this should be ignored too!" {

// test here

}

})

Once we are finished, we can just remove the “f:” prefix.

The opposite of this is also supported, which is to prefix a test with an exclamation mark and then that test (and subtests of it) will be disabled.

For example, in the next snippet we’ve disabled the first test by adding the “!” prefix.