Assert softly – when one assertion is not enough

It’s usually in our best interest to keep one assertion per test method. Yet, situation when more than one check in single test method is present may occur. Why this may be a problem?
Generally, JVM testing frameworks, such as Junit makes use of AssertionExceptions. If such exception is thrown during test block execution, test stops and renders failure.

Example

Lets consider test method with 3 assertions:

class AssertSoftlyTest : StringSpec({    "multiple assertions"{        val input = "rozkminia\n"        input shouldContain "@"        input shouldNotEndWith "\n"        input shouldHaveMaxLength 23    }})

Executing this test results in AssertionError:

If first assertions fails, we don’t have proper information about other verifications! In more complicated cases this may give us hard time finding the real problem.

Due to this limitation – one assertions per test method we should consider designing test the other way. One solution would be test input string against the regex, second – to split those checks into 3 separate test cases, or finally – combine those assertions into one assertion.

Fortunately with Kotest comes assertSoftly method. Let’s see how it works:

class AssertSoftlyTest : StringSpec({    "multiple assertions"{        val input = "rozkminia\n"        assertSoftly {            input shouldContain "@"            input shouldNotEndWith "\n"            input shouldHaveMaxLength 23        }    }})

assertSoftly collects assertion errors thrown in it’s block and re-throws MultiAssertionError:

Assert softly – 2 assertions failed

Good news is that assertSoftly does not depend heavily on the rest of Kotlin Test framework – it can be used in Junit4 and Junit5 test suites.

Having multiple assertions per one test method is usually not the best developer practice – it may lead to confusing errors and hard time during debugging.

If we can split complex verification into separate cases (and make use of some kind of assertions DSL – shouldContain)  it’s good to know that mechanism such as assertSoftly exists.

Key points:

  • first assertion error in test block stops test execution
  • assertSoftly collects and rethrows assertion errors
  • it’s OK to use multiple assertions in one test method if it increases readability

Check Kotest on Github:

kotest/kotest
Powerful, elegant and flexible test framework for Kotlin – kotest/kotest


Leave a Comment