ZIO Test is a zero-dependency testing library that makes it easy to test effectual programs
Comprehensive assertion library with combinable assertions, smart error messages, and detailed failure reporting.
Simple assertion functions for common testing scenarios.
/**
* Assert that all boolean expressions are true
* @param exprs boolean expressions to evaluate
* @return test result indicating success or failure
*/
def assertTrue(exprs: Boolean*): TestResult
/**
* Assert a value against an assertion
* @param expr value to test
* @param assertion assertion to apply
* @return test result
*/
def assert[A](expr: => A)(assertion: Assertion[A]): TestResult
/**
* Assert an effectful computation against an assertion
* @param effect ZIO effect producing value to test
* @param assertion assertion to apply to the result
* @return effectful test result
*/
def assertZIO[R, E, A](effect: ZIO[R, E, A])(assertion: Assertion[A]): ZIO[R, E, TestResult]
/**
* Assert that a test completes successfully
*/
def assertCompletes: TestResult
/**
* Assert that a test never completes (useful for timeout testing)
* @param message descriptive failure message
*/
def assertNever(message: String): TestResultUsage Examples:
import zio.test._
import zio.test.Assertion._
// Basic assertions
assertTrue(2 + 2 == 4)
assertTrue(List(1, 2, 3).nonEmpty, List(1, 2, 3).size == 3)
// Value assertions
assert(List(1, 2, 3))(hasSize(equalTo(3)))
assert("hello world")(startsWith("hello"))
assert(42)(isGreaterThan(0) && isLessThan(100))
// Effectful assertions
assertZIO(ZIO.succeed(List(1, 2, 3)))(contains(2))
assertZIO(database.getUser(123))(hasField("name", equalTo("Alice")))Core trait for building composable assertions.
/**
* An assertion that can be applied to values of type A
*/
trait Assertion[-A] {
/**
* Apply the assertion to a value
* @param value value to test
* @return test result
*/
def apply(value: A): TestResult
/**
* Combine with another assertion using logical AND
* @param that other assertion
* @return combined assertion
*/
def &&(that: Assertion[A]): Assertion[A]
/**
* Combine with another assertion using logical OR
* @param that other assertion
* @return combined assertion
*/
def ||(that: Assertion[A]): Assertion[A]
/**
* Negate this assertion
* @return negated assertion
*/
def unary_! : Assertion[A]
/**
* Add a custom label to this assertion
* @param message descriptive label
* @return labeled assertion
*/
def ??(message: String): Assertion[A]
}Fundamental assertion functions for common data types and operations.
// Equality and comparison
def equalTo[A](expected: A): Assertion[A]
def not[A](assertion: Assertion[A]): Assertion[A]
def anything: Assertion[Any]
def nothing: Assertion[Any]
// Boolean assertions
val isTrue: Assertion[Boolean]
val isFalse: Assertion[Boolean]
// Null/Option assertions
val isNull: Assertion[Any]
val isNonNull: Assertion[Any]
def isSome[A](assertion: Assertion[A]): Assertion[Option[A]]
val isNone: Assertion[Option[A]]
// Numeric comparisons
def isGreaterThan[A](reference: A)(implicit ord: Ordering[A]): Assertion[A]
def isGreaterThanEqualTo[A](reference: A)(implicit ord: Ordering[A]): Assertion[A]
def isLessThan[A](reference: A)(implicit ord: Ordering[A]): Assertion[A]
def isLessThanEqualTo[A](reference: A)(implicit ord: Ordering[A]): Assertion[A]
def isWithin[A](reference: A, tolerance: A)(implicit num: Numeric[A]): Assertion[A]
// String assertions
def startsWith(prefix: String): Assertion[String]
def endsWith(suffix: String): Assertion[String]
def containsString(substring: String): Assertion[String]
def matchesRegex(regex: Regex): Assertion[String]
def hasLength(assertion: Assertion[Int]): Assertion[String]
val isEmptyString: Assertion[String]
val isNonEmptyString: Assertion[String]Usage Examples:
import zio.test.Assertion._
// Equality and comparison
assert(42)(equalTo(42))
assert("test")(not(equalTo("other")))
// Boolean
assert(true)(isTrue)
assert(false)(isFalse)
// Numeric
assert(10)(isGreaterThan(5))
assert(3.14)(isWithin(3.0, 0.2))
// String
assert("hello world")(startsWith("hello"))
assert("hello world")(endsWith("world"))
assert("hello world")(containsString("lo wo"))
assert("abc123")(matchesRegex("\\w+\\d+".r))Assertions for testing collections, iterables, and sequences.
// Size and emptiness
def hasSize[A](assertion: Assertion[Int]): Assertion[Iterable[A]]
val isEmpty: Assertion[Iterable[Any]]
val isNonEmpty: Assertion[Iterable[Any]]
// Element membership
def contains[A](element: A): Assertion[Iterable[A]]
def containsAll[A](elements: A*): Assertion[Iterable[A]]
def exists[A](assertion: Assertion[A]): Assertion[Iterable[A]]
def forall[A](assertion: Assertion[A]): Assertion[Iterable[A]]
// Sequence operations
def startsWith[A](prefix: Seq[A]): Assertion[Seq[A]]
def endsWith[A](suffix: Seq[A]): Assertion[Seq[A]]
def hasAt[A](index: Int)(assertion: Assertion[A]): Assertion[Seq[A]]
def hasFirst[A](assertion: Assertion[A]): Assertion[Seq[A]]
def hasLast[A](assertion: Assertion[A]): Assertion[Seq[A]]
// Set operations
def isSubsetOf[A](superset: Set[A]): Assertion[Set[A]]
def isSupersetOf[A](subset: Set[A]): Assertion[Set[A]]
def intersects[A](other: Set[A]): Assertion[Set[A]]
// Map operations
def hasKey[K](key: K): Assertion[Map[K, Any]]
def hasValue[V](value: V): Assertion[Map[Any, V]]
def hasKeyValue[K, V](key: K, value: V): Assertion[Map[K, V]]Usage Examples:
import zio.test.Assertion._
val numbers = List(1, 2, 3, 4, 5)
val words = List("apple", "banana", "cherry")
// Size assertions
assert(numbers)(hasSize(equalTo(5)))
assert(List.empty[Int])(isEmpty)
// Element membership
assert(numbers)(contains(3))
assert(words)(containsAll("apple", "cherry"))
assert(numbers)(exists(isGreaterThan(3)))
assert(numbers)(forall(isGreaterThan(0)))
// Sequence operations
assert(numbers)(startsWith(Seq(1, 2)))
assert(words)(hasFirst(equalTo("apple")))
assert(numbers)(hasAt(2)(equalTo(3)))
// Map operations
val userMap = Map("id" -> 123, "name" -> "Alice")
assert(userMap)(hasKey("name"))
assert(userMap)(hasKeyValue("id", 123))Specialized assertions for testing exceptions and ZIO effects.
// Exception assertions
def throws[E <: Throwable](assertion: Assertion[E]): Assertion[Any]
def throwsA[E <: Throwable](implicit tag: ClassTag[E]): Assertion[Any]
// ZIO effect assertions
def succeeds[A](assertion: Assertion[A]): Assertion[IO[Any, A]]
def fails[E](assertion: Assertion[E]): Assertion[IO[E, Any]]
def dies(assertion: Assertion[Throwable]): Assertion[Task[Any]]
def isInterrupted: Assertion[Task[Any]]
// Cause assertions
def failsCause[E](assertion: Assertion[Cause[E]]): Assertion[IO[E, Any]]
def diesCause(assertion: Assertion[Cause[Nothing]]): Assertion[Task[Any]]
// Numeric approximation
def approximatelyEquals[A](reference: A, tolerance: A)(implicit
num: Numeric[A]
): Assertion[A]
// Additional ZIO effect assertions
def isInterruptedOnly: Assertion[Task[Any]]
def completes: Assertion[ZIO[Any, Any, Any]]
def completesWithin(duration: Duration): Assertion[ZIO[Any, Any, Any]]Usage Examples:
import zio.test.Assertion._
// Exception testing
def divide(a: Int, b: Int): Int =
if (b == 0) throw new ArithmeticException("Division by zero")
else a / b
assert(divide(10, 0))(throws(isSubtype[ArithmeticException](anything)))
// ZIO effect testing
val successEffect = ZIO.succeed(42)
val failureEffect = ZIO.fail("error")
val dieEffect = ZIO.die(new RuntimeException("boom"))
assert(successEffect)(succeeds(equalTo(42)))
assert(failureEffect)(fails(equalTo("error")))
assert(dieEffect)(dies(isSubtype[RuntimeException](anything)))Assertions for testing object properties and fields.
/**
* Assert on a field of an object
* @param name field name (for error reporting)
* @param proj projection function to extract field value
* @param assertion assertion to apply to field value
*/
def hasField[A, B](name: String, proj: A => B, assertion: Assertion[B]): Assertion[A]
/**
* Convenience method for testing case class fields by name
*/
def hasField[A, B](name: String, assertion: Assertion[B])(implicit proj: A => B): Assertion[A]Usage Examples:
import zio.test.Assertion._
case class User(id: Int, name: String, email: String, active: Boolean)
val user = User(123, "Alice", "alice@example.com", true)
// Field assertions
assert(user)(hasField("id", _.id, equalTo(123)))
assert(user)(hasField("name", _.name, startsWith("A")))
assert(user)(hasField("active", _.active, isTrue))
// Combined field assertions
assert(user)(
hasField("id", _.id, isGreaterThan(0)) &&
hasField("name", _.name, isNonEmptyString) &&
hasField("email", _.email, matchesRegex(".*@.*".r))
)Core type representing the outcome of test assertions.
/**
* Result of a test assertion
*/
trait TestResult {
/**
* True if the test succeeded
*/
def isSuccess: Boolean
/**
* True if the test failed
*/
def isFailure: Boolean
/**
* Add a custom message to this result
* @param message descriptive message
* @return test result with message
*/
def ??(message: String): TestResult
/**
* Combine with another test result using logical AND
*/
def &&(that: TestResult): TestResult
/**
* Combine with another test result using logical OR
*/
def ||(that: TestResult): TestResult
/**
* Negate this test result
*/
def unary_! : TestResult
}
object TestResult {
case class Succeeded(result: BoolAlgebra[AssertionValue]) extends TestResult
case class Failed(result: BoolAlgebra[AssertionValue]) extends TestResult
val succeed: TestResult
val fail: TestResult
}/**
* Represents test failures with detailed information
*/
sealed trait TestFailure[+E] {
def map[E1](f: E => E1): TestFailure[E1]
}
object TestFailure {
case class Assertion(result: TestResult) extends TestFailure[Nothing]
case class Runtime[E](cause: Cause[E]) extends TestFailure[E]
}
/**
* Represents successful test completion
*/
case class TestSuccess() extends AnyValInstall with Tessl CLI
npx tessl i tessl/maven-dev-zio--zio-test-2-12