Atrium is another assertion library written in Kotlin.

Atrium is designed to support different APIs, different reporting styles and Internationalization (i18n). The core of Atrium as well as the builders to create sophisticated assertions are designed to be extensible and thus allow you to extend or replace components easily.

It is very powerful, but also quite complex compared to AssertJ and Strikt.

The first step is to choose which JAR(s) to depend on. Atrium is available in several flavors:

Infix-oriented Infix allows to call the fluent API without dots: assert ( x ). toBe ( 2 ) assert ( x ) toBe 2 Verb The default assertion verb is assert() . Two other verbs are available out-of-the-box: assertThat() and check() . It’s also possible to create your own verb. Localized Failed assertion messages are available in English and in German.

Depending on which flavors are desired, different JAR combinations need to be referenced. The following snippet will use a no-infix, assert() and English messages:

<dependency> <groupId> ch.tutteli.atrium </groupId> <artifactId> atrium-cc-en_GB-robstoll </artifactId> <version> 0.7.0 </version> <scope> test </scope> </dependency>

Basic assertions look quite alike to AssertJ’s and Strikt’s':

@Test fun `assert that frodo ' s name is equal to Frodo` () { assert ( frodo . name ). toBe ( "Frodo" ) } @Test fun `assert that frodo is not sauron` () { assert ( frodo ). isNotSameAs ( sauron ) }

However, Atrium’s API allows an alternative fully-typesafe way of writing:

@Test fun `assert that frodo ' s name is equal to Frodo 2 ` () { assert ( frodo ) { property ( subject :: name ). toBe ( "Frodo" ) } }

It can adapt depending on one’s own taste. Here’s are 4 different ways on writing the same assertion on a String :

@Test fun `assert that frodo starts with Fro and ends with do ` () { assert ( frodo . name ) . startsWith ( "Fro" ) . endsWith ( "do" ) . isSameAs ( "Frodo" ) } @Test fun `assert that frodo starts with Fro and ends with do 2 ` () { assert ( frodo . name ) { startsWith ( "Fro" ) endsWith ( "do" ) isSameAs ( "Frodo" ) } } @Test fun `assert that frodo starts with Fro and ends with do 3 ` () { assert ( frodo ) { property ( subject :: name ) . startsWith ( "Fro" ) . endsWith ( "do" ) . isSameAs ( "Frodo" ) } } @Test fun `assert that frodo starts with Fro and ends with do 4 ` () { assert ( frodo ) { property ( subject :: name ) { startsWith ( "Fro" ) endsWith ( "do" ) isSameAs ( "Frodo" ) } } }

As AssertJ and Strikt, Atrium offers an API to execute assertions on collections:

@Test fun `assert that fellowship of the ring has size 9 , contains frodo and sam , and does not contain sauron` () { assert ( fellowshipOfTheRing ) . hasSize ( 9 ) . contains ( frodo , sam ) . containsNot ( sauron ) } @Test fun `assert that fellowship of the ring members ' names contains Boromir , Gandalf , Frodo and Legolas and does not contain Sauron and Elrond` () { assert ( fellowshipOfTheRing . map { it . name }) (1) . containsNot ( "Sauron" , "Elrond" ) (2) (3) } @Test fun `assert that fellowship of the ring members ' name containing 'o' are only aragorn , frodo , legolas and boromir` () { assert ( fellowshipOfTheRing . filter { it . name . contains ( "o" ) }) (1) . contains . inAnyOrder . only . values ( aragorn , frodo , legolas , boromir ) (2) (4) }

1 As Strikt, Atrium has no specific API for map and filter. One needs to rely on Kotlin’s API. 2 Classical contain/does not contain assertions are available. 3 Shortcut assertion 4 Full-blown customizable assertion

I found no way to refine assertions in a pipeline. The only option is to call different asserts:

@Test fun `assert that fellowship of the ring members ' name containing 'o' are of race HOBBIT , ELF and MAN` () { val fellowshipOfTheRingMembersWhichNameContainsO = fellowshipOfTheRing . filter { it . name . contains ( "o" ) } assert ( fellowshipOfTheRingMembersWhichNameContainsO ) . contains . inAnyOrder . only . values ( aragorn , frodo , legolas , boromir ) assert ( fellowshipOfTheRingMembersWhichNameContainsO . map { it . race . label }. distinct ()) . containsStrictly ( "Hobbit" , "Elf" , "Man" ) }

With that approach, the first failed assertion will throw an exception, and short-circuit the test flow so that potentially other failing assertions won’t be executed.