Core assertion and matcher library for Kotest testing framework
—
The Core DSL provides the fundamental assertion functions and matcher infrastructure that form the foundation of all other matchers in Kotest Assertions.
The core assertion functions provide the main entry points for testing values.
/**
* Assert that this value should be equal to the expected value
* @param expected The expected value to compare against
* @return The original value for chaining
*/
infix fun <T, U : T> T.shouldBe(expected: U?): T
/**
* Assert that this value should not be equal to the given value
* @param any The value that this should not equal
* @return The original value for chaining
*/
infix fun <T> T.shouldNotBe(any: Any?): T
/**
* Assert that this value should match the given matcher
* @param matcher The matcher to apply to this value
* @return The original value for chaining
*/
infix fun <T> T.should(matcher: Matcher<T>): T
/**
* Assert that this value should not match the given matcher
* @param matcher The matcher that this value should not match
* @return The original value for chaining
*/
infix fun <T> T.shouldNot(matcher: Matcher<T>): TUsage Examples:
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.should
import io.kotest.matchers.shouldNot
import io.kotest.matchers.string.startWith
// Basic equality assertions
val name = "Alice"
name shouldBe "Alice"
name shouldNotBe "Bob"
// Using matchers
name should startWith("Al")
name shouldNot startWith("Bo")
// Chaining assertions
val result = processData()
result shouldBe "processed" shouldBe "processed"The core abstraction that enables composable and reusable assertion logic.
/**
* Core matcher interface that defines how values are tested
*/
interface Matcher<T> {
/**
* Test a value against this matcher
* @param value The value to test
* @return Result containing pass/fail status and messages
*/
fun test(value: T): MatcherResult
/**
* Transform this matcher to work with a different input type
* @param f Function to convert from U to T
* @return New matcher that accepts type U
*/
infix fun <U> contramap(f: (U) -> T): Matcher<U>
/**
* Create a matcher with inverted logic
* @return Matcher that passes when this matcher fails
*/
fun invert(): Matcher<T>
}Result types that provide detailed information about assertion outcomes.
/**
* Base result interface for matcher operations
*/
interface MatcherResult {
/**
* Whether the matcher test passed
*/
fun passed(): Boolean
/**
* Message shown when the test fails
*/
fun failureMessage(): String
/**
* Message shown when the negated test fails
*/
fun negatedFailureMessage(): String
}
/**
* Enhanced result with comparison details for ordered types
*/
interface ComparableMatcherResult : MatcherResult {
/**
* String representation of the actual value
*/
fun actual(): String
/**
* String representation of the expected value
*/
fun expected(): String
}
/**
* Enhanced result for equality-based assertions
*/
interface EqualityMatcherResult : MatcherResult {
/**
* The actual value being tested
*/
fun actual(): Any?
/**
* The expected value for comparison
*/
fun expected(): Any?
}Core utility functions for creating common matchers.
/**
* Create an equality matcher
* @param expected The value to match against
* @return Matcher that checks for equality
*/
fun <T> be(expected: T): Matcher<T>
/**
* Create a matcher that always passes
* @return Matcher that never fails
*/
fun <T> any(): Matcher<T>
/**
* Combine multiple matchers with AND logic
* @param matchers Variable number of matchers to combine
* @return Matcher that passes only if all input matchers pass
*/
fun <T> allOf(vararg matchers: Matcher<T>): Matcher<T>
/**
* Combine multiple matchers with OR logic
* @param matchers Variable number of matchers to combine
* @return Matcher that passes if any input matcher passes
*/
fun <T> anyOf(vararg matchers: Matcher<T>): Matcher<T>Usage Examples:
import io.kotest.matchers.*
import io.kotest.matchers.string.*
// Using matcher factories
val value = "Hello World"
value should be("Hello World")
value should anyOf(startWith("Hi"), startWith("Hello"))
// Creating custom matchers
fun <T> beOneOf(vararg options: T): Matcher<T> = object : Matcher<T> {
override fun test(value: T): MatcherResult =
if (value in options) MatcherResult.Success
else MatcherResult.failure("$value should be one of ${options.toList()}")
}
// Using custom matcher
val status = "active"
status should beOneOf("active", "inactive", "pending")Advanced patterns for combining and transforming matchers.
/**
* Transform a matcher to work with nullable types
* @param matcher The base matcher for non-null values
* @return Matcher that handles null values appropriately
*/
fun <T> Matcher<T>.orNull(): Matcher<T?>
/**
* Transform a matcher to work with collection elements
* @param matcher The matcher to apply to each element
* @return Matcher that tests all collection elements
*/
fun <T> Matcher<T>.forAll(): Matcher<Collection<T>>
/**
* Transform a matcher to work with at least one collection element
* @param matcher The matcher to apply to elements
* @return Matcher that passes if any element matches
*/
fun <T> Matcher<T>.forAny(): Matcher<Collection<T>>The core DSL provides detailed error messages that help identify assertion failures:
All assertion functions throw AssertionError on failure, which integrates seamlessly with testing frameworks.
Install with Tessl CLI
npx tessl i tessl/maven-io-kotest--kotest-assertions-core-jvm