or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

assertions.mdindex.mdmocking.mdproperty-testing.mdtest-aspects.mdtest-environment.mdtest-execution.mdtest-specifications.md
tile.json

tessl/maven-dev-zio--zio-test_2-13

ZIO Test is a featherweight testing library for effectful programs

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/dev.zio/zio-test_2.13@1.0.x

To install, run

npx @tessl/cli install tessl/maven-dev-zio--zio-test_2-13@1.0.0

index.mddocs/

ZIO Test

ZIO Test is a featherweight testing library for effectful programs. It treats every test specification as an immutable value, enabling powerful composition and transformation capabilities. The library provides tight integration with ZIO effects, allowing developers to test asynchronous and complex computational workflows naturally without the need for complex async value wrapping or multiple unsafeRun calls.

Package Information

  • Package Name: zio-test
  • Package Type: maven
  • Language: Scala
  • Installation: libraryDependencies += "dev.zio" %% "zio-test" % "1.0.18"

Core Imports

import zio.test._
import zio.test.Assertion._
import zio.test.environment._

For specific functionality:

// Core testing DSL
import zio.test.{test, testM, suite, assert, assertM, assertTrue}

// Assertions
import zio.test.Assertion.{equalTo, isTrue, contains, hasSize}

// Property testing
import zio.test.{Gen, check, checkAll}

// Test environment
import zio.test.environment.{TestEnvironment, TestClock, TestConsole, TestRandom}

// Runnable specs
import zio.test.DefaultRunnableSpec

Basic Usage

import zio.test._
import zio.test.Assertion._
import zio.test.environment._

object MyTestSpec extends DefaultRunnableSpec {
  def spec = suite("My Test Suite")(
    test("basic assertion") {
      assert(2 + 2)(equalTo(4))
    },
    testM("effectful test") {
      for {
        result <- ZIO.succeed(42)
      } yield assert(result)(equalTo(42))
    },
    test("boolean assertion") {
      assertTrue(2 + 2 == 4, "hello".length == 5)
    }
  )
}

Architecture

ZIO Test is built around several key components:

  • Test Specifications: Spec and ZSpec types that compose into test suites and individual tests
  • Assertion System: Rich assertion library with composable assertions and detailed failure reporting
  • Property Testing: Gen generators with automatic shrinking for property-based testing
  • Test Environment: Controllable versions of ZIO services (Clock, Console, Random, System) for deterministic testing
  • Test Execution: Runners and executors for running test suites with configurable behavior
  • Mocking Framework: Complete mocking system for testing with controlled dependencies
  • Test Aspects: Composable transformations for test behavior (retry, timeout, parallel execution, etc.)

Capabilities

Test Specifications

Core DSL for defining test suites and individual tests with full ZIO integration and composition support.

def test(label: String)(assertion: => TestResult)(implicit loc: SourceLocation): ZSpec[Any, Nothing]
def testM[R, E](label: String)(assertion: => ZIO[R, E, TestResult])(implicit loc: SourceLocation): ZSpec[R, E]
def suite[R, E, T](label: String)(specs: Spec[R, E, T]*): Spec[R, E, T]
def suiteM[R, E, T](label: String)(specs: ZIO[R, E, Iterable[Spec[R, E, T]]]): Spec[R, E, T]

Test Specifications

Assertion Framework

Rich assertion system with over 50 built-in assertions, logical combinators, and detailed failure reporting.

def assert[A](value: => A)(assertion: Assertion[A]): TestResult
def assertM[R, E, A](effect: ZIO[R, E, A])(assertion: AssertionM[A]): ZIO[R, E, TestResult]
def assertTrue(exprs: Boolean*): TestResult

trait Assertion[A] {
  def run(actual: A): AssertResult
  def &&(that: Assertion[A]): Assertion[A]
  def ||(that: Assertion[A]): Assertion[A]
  def unary_!: Assertion[A]
}

Assertion Framework

Property Testing

Comprehensive property-based testing with generators, automatic shrinking, and configurable test execution.

def check[R <: TestConfig, A](rv: Gen[R, A])(test: A => TestResult): URIO[R, TestResult]
def checkM[R <: TestConfig, R1 <: R, E, A](rv: Gen[R, A])(test: A => ZIO[R1, E, TestResult]): ZIO[R1, E, TestResult]
def checkAll[R <: TestConfig, A](rv: Gen[R, A])(test: A => TestResult): URIO[R, TestResult]

abstract class Gen[-R, +A] {
  def map[B](f: A => B): Gen[R, B]
  def flatMap[R1 <: R, B](f: A => Gen[R1, B]): Gen[R1, B]
  def filter(f: A => Boolean): Gen[R, A]
}

Property Testing

Test Environment

Controllable test services that replace ZIO's standard environment for deterministic testing.

object TestClock {
  def adjust(duration: Duration): URIO[TestClock, Unit]
  def setDateTime(dateTime: OffsetDateTime): URIO[TestClock, Unit]
  def setTime(duration: Duration): URIO[TestClock, Unit]
  def sleeps: URIO[TestClock, List[Duration]]
}

object TestConsole {
  def feedLines(lines: String*): URIO[TestConsole, Unit]
  def output: URIO[TestConsole, Vector[String]]
  def clearOutput: URIO[TestConsole, Unit]
  def clearInput: URIO[TestConsole, Unit]
}

object TestRandom {
  def feedInts(ints: Int*): URIO[TestRandom, Unit]
  def feedDoubles(doubles: Double*): URIO[TestRandom, Unit]
  def setSeed(seed: Long): URIO[TestRandom, Unit]
}

object TestSystem {
  def putProperty(name: String, value: String): URIO[TestSystem, Unit]
  def putEnv(name: String, value: String): URIO[TestSystem, Unit]
  def clearProperty(prop: String): URIO[TestSystem, Unit]
  def clearEnv(variable: String): URIO[TestSystem, Unit]
}

Test Environment

Mocking Framework

Complete mocking system for creating controlled test doubles with expectation-based verification.

abstract class Mock[-M <: Has[_]] {
  def expects[I, A](capability: Capability[M, I, A]): Expectation[I]
}

sealed trait Expectation[-I] {
  def and[I1 <: I](that: Expectation[I1]): Expectation[I1]
  def repeats(range: Range): Expectation[I]
  def returns[A](value: A): Expectation[I]
  def returnsM[R, E, A](effect: ZIO[R, E, A]): Expectation[I]
}

Mocking Framework

Test Execution

Test runners and executors for running test suites with configurable behavior and reporting.

case class TestRunner[+R, -E](executor: TestExecutor[R, E]) {
  def run[R1 <: R, E1 >: E](spec: ZSpec[R1, E1]): URIO[R1, ExecutedSpec[E1]]
}

abstract class DefaultRunnableSpec extends RunnableSpec[TestEnvironment, Any] {
  def spec: ZSpec[TestEnvironment, Any]
}

Test Execution

Test Aspects

Composable test transformations for modifying test behavior including retry, timeout, and parallel execution.

abstract class TestAspect[+LowerR, -UpperR, +LowerE, -UpperE] {
  def apply[R, E](spec: ZSpec[R, E]): ZSpec[R, E]
}

// Control aspects
val ignore: TestAspectPoly
val flaky: TestAspectPoly
val parallel: TestAspectPoly
def timeout(duration: Duration): TestAspectAtLeastR[Live]
def eventually: TestAspectAtLeastR[Live with Annotations]

// Configuration aspects  
def samples(n: Int): TestAspectAtLeastR[TestConfig]
def shrinks(n: Int): TestAspectAtLeastR[TestConfig]
def repeats(n: Int): TestAspectAtLeastR[TestConfig]
def retries(n: Int): TestAspectAtLeastR[TestConfig]

// Lifecycle aspects
def before[R](effect: ZIO[R, Nothing, Any]): TestAspectAtLeastR[R]
def after[R](effect: ZIO[R, Nothing, Any]): TestAspectAtLeastR[R]
def around[R, A](before: ZIO[R, Nothing, A])(after: A => ZIO[R, Nothing, Any]): TestAspectAtLeastR[R]

Test Aspects

Types

type ZTest[-R, +E] = ZIO[R, TestFailure[E], TestSuccess]
type ZSpec[-R, +E] = Spec[R, TestFailure[E], TestSuccess]
type TestResult = BoolAlgebra[AssertionResult]
type ZTestEnv = TestClock with TestConsole with TestRandom with TestSystem
type TestEnvironment = ZTestEnv with Live
type Annotated[+A] = (A, TestAnnotationMap)

// Core service types
type TestConfig = Has[TestConfig.Service]
type Annotations = Has[Annotations.Service]
type Sized = Has[Sized.Service]
type TestLogger = Has[TestLogger.Service]

// Aspect type aliases
type TestAspectPoly = TestAspect[Nothing, Any, Nothing, Any]
type TestAspectAtLeastR[R] = TestAspect[Nothing, R, Nothing, Any]

case class Spec[-R, +E, +T](caseValue: SpecCase[R, E, T, Spec[R, E, T]])

sealed trait TestSuccess
object TestSuccess {
  case class Succeeded(result: BoolAlgebra[Unit]) extends TestSuccess
  case object Ignored extends TestSuccess
}

sealed trait TestFailure[+E]
object TestFailure {
  case class Assertion(result: BoolAlgebra[AssertionResult]) extends TestFailure[Nothing]
  case class Runtime[+E](cause: Cause[E]) extends TestFailure[E]
}