Comprehensive assertion system with 100+ built-in assertions for testing values, collections, exceptions, and more. The assertion library provides both simple equality checks and complex structural validations.
The fundamental assertion type that powers all ZIO Test assertions.
/**
* Core assertion type for testing values of type A
*/
case class Assertion[-A](arrow: TestArrow[A, Boolean]) {
/** Combine assertions with logical AND */
def &&[A1 <: A](that: Assertion[A1]): Assertion[A1]
/** Combine assertions with logical OR */
def ||[A1 <: A](that: Assertion[A1]): Assertion[A1]
/** Negate this assertion */
def unary_! : Assertion[A]
/** Test a value against this assertion */
def test(value: A)(implicit sourceLocation: SourceLocation): Boolean
/** Run assertion and return TestResult */
def run(value: => A)(implicit sourceLocation: SourceLocation): TestResult
/** Add label to assertion for better error messages */
def label(message: String): Assertion[A]
}Essential assertion functions available in the package object.
/**
* Asserts that the given test was completed
*/
def assertCompletes(implicit trace: Trace, sourceLocation: SourceLocation): TestResult
/**
* Effectful version of assertCompletes
*/
def assertCompletesZIO(implicit trace: Trace, sourceLocation: SourceLocation): UIO[TestResult]
/**
* Asserts that the given test was never completed
*/
def assertNever(message: String)(implicit trace: Trace, sourceLocation: SourceLocation): TestResultFunctions for creating custom assertions from predicates and transformations.
/**
* Creates a new assertion from a function
* @param name - Name of the assertion for error reporting
* @param run - Function that tests the assertion condition
* @return New Assertion instance
*/
def assertion[A](name: String)(run: (=> A) => Boolean): Assertion[A]
/**
* Creates a recursive assertion that transforms input before testing
* @param name - Name of the assertion
* @param assertion - Assertion to apply to transformed value
* @param get - Function to extract testable value from input
* @return New Assertion instance
*/
def assertionRec[A, B](name: String)(assertion: Assertion[B])(get: A => Option[B]): Assertion[A]Usage Examples:
import zio.test._
import zio.test.Assertion._
// Custom assertion for even numbers
val isEven = assertion[Int]("isEven")(n => n % 2 == 0)
test("custom assertions") {
assert(4)(isEven) &&
assert(List(2, 4, 6))(forall(isEven))
}
// Recursive assertion for optional fields
val hasValidEmail = assertionRec[User, String]("hasValidEmail")(
containsString("@")
)(user => user.email)
test("recursive assertions") {
val user = User("Alice", Some("alice@example.com"))
assert(user)(hasValidEmail)
}Fundamental equality and comparison assertions.
/**
* Asserts that the value equals the expected value
*/
def equalTo[A](expected: A): Assertion[A]
/**
* Asserts that the value does not equal the specified value
*/
def not[A](assertion: Assertion[A]): Assertion[A]
/**
* Asserts that the value is one of the specified values
*/
def isOneOf[A](values: A*): Assertion[A]
/**
* Asserts that the value is a subtype of the specified type
*/
def isSubtype[A, B <: A](implicit classTag: ClassTag[B]): Assertion[A]Assertions for numeric comparisons and ranges.
/**
* Asserts that the numeric value is approximately equal within tolerance
*/
def approximatelyEquals[A: Numeric](expected: A, tolerance: A): Assertion[A]
/**
* Asserts that the value is less than expected
*/
def isLessThan[A: Ordering](expected: A): Assertion[A]
/**
* Asserts that the value is less than or equal to expected
*/
def isLessThanEqualTo[A: Ordering](expected: A): Assertion[A]
/**
* Asserts that the value is greater than expected
*/
def isGreaterThan[A: Ordering](expected: A): Assertion[A]
/**
* Asserts that the value is greater than or equal to expected
*/
def isGreaterThanEqualTo[A: Ordering](expected: A): Assertion[A]
/**
* Asserts that the numeric value is within the specified range
*/
def isWithin[A: Numeric](min: A, max: A): Assertion[A]
/**
* Asserts that the numeric value is positive
*/
def isPositive[A: Numeric]: Assertion[A]
/**
* Asserts that the numeric value is negative
*/
def isNegative[A: Numeric]: Assertion[A]
/**
* Asserts that the numeric value is zero
*/
def isZero[A: Numeric]: Assertion[A]
/**
* Asserts that the numeric value is non-negative (>= 0)
*/
def nonNegative[A: Numeric]: Assertion[A]
/**
* Asserts that the numeric value is non-positive (<= 0)
*/
def nonPositive[A: Numeric]: Assertion[A]Usage Examples:
import zio.test._
import zio.test.Assertion._
test("numeric assertions") {
assert(42)(equalTo(42)) &&
assert(3.14159)(approximatelyEquals(3.14, 0.01)) &&
assert(10)(isGreaterThan(5)) &&
assert(10)(isLessThanEqualTo(10)) &&
assert(7)(isWithin(5, 10)) &&
assert(42)(isPositive) &&
assert(-5)(isNegative) &&
assert(0)(isZero)
}Comprehensive assertions for testing collections, sequences, and iterables.
/**
* Asserts that the collection contains the specified element
*/
def contains[A](expected: A): Assertion[Iterable[A]]
/**
* Asserts that at least one element satisfies the assertion
*/
def exists[A](assertion: Assertion[A]): Assertion[Iterable[A]]
/**
* Asserts that all elements satisfy the assertion
*/
def forall[A](assertion: Assertion[A]): Assertion[Iterable[A]]
/**
* Asserts that the collection has the specified size
*/
def hasSize[A](expected: Int): Assertion[Iterable[A]]
/**
* Asserts that the collection has the element at the specified index
*/
def hasAt[A](index: Int)(assertion: Assertion[A]): Assertion[Seq[A]]
/**
* Asserts that the first element satisfies the assertion
*/
def hasFirst[A](assertion: Assertion[A]): Assertion[Iterable[A]]
/**
* Asserts that the last element satisfies the assertion
*/
def hasLast[A](assertion: Assertion[A]): Assertion[Iterable[A]]
/**
* Asserts that the collection is empty
*/
def isEmpty: Assertion[Iterable[Any]]
/**
* Asserts that the collection is non-empty
*/
def isNonEmpty: Assertion[Iterable[Any]]
/**
* Asserts that elements are distinct (no duplicates)
*/
def isDistinct[A]: Assertion[Iterable[A]]
/**
* Asserts that the collection is sorted according to natural ordering
*/
def isSorted[A: Ordering]: Assertion[Seq[A]]
/**
* Asserts that the collection is sorted in reverse order
*/
def isSortedReverse[A: Ordering]: Assertion[Seq[A]]Usage Examples:
import zio.test._
import zio.test.Assertion._
test("collection assertions") {
val numbers = List(1, 2, 3, 4, 5)
val empty = List.empty[Int]
val sorted = List(1, 3, 5, 7, 9)
assert(numbers)(contains(3)) &&
assert(numbers)(hasSize(5)) &&
assert(numbers)(forall(isPositive)) &&
assert(numbers)(exists(equalTo(4))) &&
assert(numbers)(hasFirst(equalTo(1))) &&
assert(numbers)(hasLast(equalTo(5))) &&
assert(numbers)(hasAt(2)(equalTo(3))) &&
assert(numbers)(isNonEmpty) &&
assert(empty)(isEmpty) &&
assert(sorted)(isSorted) &&
assert(List(1, 2, 3, 1))(not(isDistinct))
}Assertions for set-like operations on collections.
/**
* Asserts that collections have the same elements (order-independent)
*/
def hasSameElements[A](expected: Iterable[A]): Assertion[Iterable[A]]
/**
* Asserts that collections have the same distinct elements
*/
def hasSameElementsDistinct[A](expected: Iterable[A]): Assertion[Iterable[A]]
/**
* Asserts that the collection is a subset of expected
*/
def hasSubset[A](expected: Iterable[A]): Assertion[Iterable[A]]
/**
* Asserts that collections have non-empty intersection
*/
def hasIntersection[A](expected: Iterable[A]): Assertion[Iterable[A]]
/**
* Asserts that the collection contains at least one of the expected elements
*/
def hasAtLeastOneOf[A](expected: Iterable[A]): Assertion[Iterable[A]]
/**
* Asserts that the collection contains at most one of the expected elements
*/
def hasAtMostOneOf[A](expected: Iterable[A]): Assertion[Iterable[A]]
/**
* Asserts that the collection contains exactly one of the expected elements
*/
def hasOneOf[A](expected: Iterable[A]): Assertion[Iterable[A]]
/**
* Asserts that the collection contains none of the expected elements
*/
def hasNoneOf[A](expected: Iterable[A]): Assertion[Iterable[A]]Assertions specific to ordered sequences.
/**
* Asserts that the sequence starts with the expected prefix
*/
def startsWith[A](expected: Seq[A]): Assertion[Seq[A]]
/**
* Asserts that the sequence ends with the expected suffix
*/
def endsWith[A](expected: Seq[A]): Assertion[Seq[A]]Specialized assertions for map-like collections.
/**
* Asserts that the map contains the specified key
*/
def hasKey[K](expected: K): Assertion[Map[K, Any]]
/**
* Asserts that the map contains all specified keys
*/
def hasKeys[K](expected: K*): Assertion[Map[K, Any]]
/**
* Asserts that the map contains all specified values
*/
def hasValues[V](expected: V*): Assertion[Map[Any, V]]String-specific assertion functions.
/**
* Asserts that the string contains the expected substring
*/
def containsString(expected: String): Assertion[String]
/**
* Asserts that the string starts with the expected prefix
*/
def startsWithString(expected: String): Assertion[String]
/**
* Asserts that the string ends with the expected suffix
*/
def endsWithString(expected: String): Assertion[String]
/**
* Asserts that strings are equal ignoring case
*/
def equalsIgnoreCase(expected: String): Assertion[String]
/**
* Asserts that the string matches the regex pattern
*/
def matchesRegex(regex: String): Assertion[String]
/**
* Asserts that the string has the specified length
*/
def hasSizeString(expected: Int): Assertion[String]Usage Examples:
import zio.test._
import zio.test.Assertion._
test("string assertions") {
val text = "Hello World"
val email = "user@example.com"
assert(text)(containsString("World")) &&
assert(text)(startsWithString("Hello")) &&
assert(text)(endsWithString("World")) &&
assert(text)(hasSizeString(11)) &&
assert("HELLO")(equalsIgnoreCase("hello")) &&
assert(email)(matchesRegex(".*@.*\\..*"))
}Assertions for Option values.
/**
* Asserts that the Option is Some and the value satisfies the assertion
*/
def isSome[A](assertion: Assertion[A]): Assertion[Option[A]]
/**
* Asserts that the Option is None
*/
def isNone: Assertion[Option[Any]]Assertions for Either values.
/**
* Asserts that the Either is Left and the value satisfies the assertion
*/
def isLeft[A](assertion: Assertion[A]): Assertion[Either[A, Any]]
/**
* Asserts that the Either is Right and the value satisfies the assertion
*/
def isRight[A](assertion: Assertion[A]): Assertion[Either[Any, A]]Assertions for Try values.
/**
* Asserts that the Try is Success and the value satisfies the assertion
*/
def isSuccess[A](assertion: Assertion[A]): Assertion[scala.util.Try[A]]
/**
* Asserts that the Try is Failure and the exception satisfies the assertion
*/
def isFailure[A](assertion: Assertion[Throwable]): Assertion[scala.util.Try[A]]Assertions for ZIO Exit values.
/**
* Asserts that the Exit succeeded and the value satisfies the assertion
*/
def succeeds[A](assertion: Assertion[A]): Assertion[Exit[Any, A]]
/**
* Asserts that the Exit failed and the error satisfies the assertion
*/
def fails[E](assertion: Assertion[E]): Assertion[Exit[E, Any]]
/**
* Asserts that the Exit died and the throwable satisfies the assertion
*/
def dies(assertion: Assertion[Throwable]): Assertion[Exit[Any, Any]]
/**
* Asserts that the Exit died with a specific throwable type
*/
def diesWithA[A: ClassTag]: Assertion[Exit[Any, Any]]
/**
* Asserts that the Exit failed with a specific error type
*/
def failsWithA[A: ClassTag]: Assertion[Exit[A, Any]]
/**
* Asserts that the Exit contains the specified cause
*/
def containsCause[E](assertion: Assertion[Cause[E]]): Assertion[Exit[E, Any]]Usage Examples:
import zio.test._
import zio.test.Assertion._
test("exit assertions") {
val success = Exit.succeed(42)
val failure = Exit.fail("error")
val die = Exit.die(new RuntimeException("boom"))
assert(success)(succeeds(equalTo(42))) &&
assert(failure)(fails(equalTo("error"))) &&
assert(die)(dies(hasMessage(containsString("boom"))))
}Assertions for testing exception properties.
/**
* Asserts that evaluating the expression throws an exception satisfying the assertion
*/
def throws[A](assertion: Assertion[Throwable]): Assertion[() => A]
/**
* Asserts that evaluating the expression throws a specific exception type
*/
def throwsA[E: ClassTag]: Assertion[() => Any]
/**
* Asserts that the throwable has the specified message
*/
def hasMessage(expected: String): Assertion[Throwable]
/**
* Asserts that the throwable has suppressed exceptions satisfying the assertion
*/
def hasSuppressed(assertion: Assertion[Iterable[Throwable]]): Assertion[Throwable]
/**
* Asserts that the throwable has a cause satisfying the assertion
*/
def hasThrowableCause(assertion: Assertion[Throwable]): Assertion[Throwable]Usage Examples:
import zio.test._
import zio.test.Assertion._
test("exception assertions") {
val divideByZero = () => 1 / 0
val exception = new IllegalArgumentException("Invalid input")
assert(divideByZero)(throwsA[ArithmeticException]) &&
assert(exception)(hasMessage(containsString("Invalid")))
}