Essential functions and types for creating test specifications and organizing test suites. These form the foundation of all ZIO Test usage.
Creates a labeled test suite containing multiple test specifications.
/**
* Builds a suite containing a number of other specs
* @param label - The name/description of the test suite
* @param specs - The test specifications to include in the suite
* @return A Spec that represents the test suite
*/
def suite[In](label: String)(specs: In*)(implicit
suiteConstructor: SuiteConstructor[In],
sourceLocation: SourceLocation,
trace: Trace
): Spec[suiteConstructor.OutEnvironment, suiteConstructor.OutError]Usage Examples:
import zio.test._
// Simple suite with multiple tests
suite("Math Operations")(
test("addition") {
assertTrue(2 + 2 == 4)
},
test("multiplication") {
assertTrue(3 * 4 == 12)
}
)
// Nested suites
suite("Calculator")(
suite("Basic Operations")(
test("add") { assertTrue(1 + 1 == 2) },
test("subtract") { assertTrue(5 - 3 == 2) }
),
suite("Advanced Operations")(
test("power") { assertTrue(Math.pow(2, 3) == 8) }
)
)Creates a single test with a descriptive label and assertion.
/**
* Builds a spec with a single test
* @param label - The name/description of the test
* @param assertion - The test assertion or effectful computation
* @return A test specification
*/
def test[In](label: String)(assertion: => In)(implicit
testConstructor: TestConstructor[Nothing, In],
sourceLocation: SourceLocation,
trace: Trace
): testConstructor.OutUsage Examples:
import zio.test._
// Simple assertion test
test("string length") {
assertTrue("hello".length == 5)
}
// Effectful test
test("async operation") {
for {
result <- ZIO.succeed(42)
_ <- ZIO.sleep(100.millis)
} yield assertTrue(result > 40)
}
// Multiple assertions
test("list operations") {
val numbers = List(1, 2, 3, 4, 5)
assertTrue(
numbers.contains(3) &&
numbers.size == 5 &&
numbers.head == 1 &&
numbers.last == 5
)
}The core type representing test specifications that can be executed.
/**
* A Spec[R, E] is the backbone of ZIO Test. Every spec is either a suite,
* which contains other specs, or a test. All specs require an environment of
* type R and may potentially fail with an error of type E.
*/
final case class Spec[-R, +E](caseValue: SpecCase[R, E, Spec[R, E]]) {
/** Combines this spec with the specified spec */
def +[R1 <: R, E1 >: E](that: Spec[R1, E1]): Spec[R1, E1]
/** Apply test aspect to this spec */
def @@[R0 <: R1, R1 <: R, E0 >: E, E1 >: E0](
aspect: TestAspect[R0, R1, E0, E1]
)(implicit trace: Trace): Spec[R1, E0]
/** Annotate each test with the specified annotation */
def annotate[V](key: TestAnnotation[V], value: V)(implicit trace: Trace): Spec[R, E]
/** Execute this spec with the given execution strategy */
def execute(defExec: ExecutionStrategy)(implicit trace: Trace): ZIO[R with Scope, Nothing, Spec[Any, E]]
}Type alias for effectfully produced tests.
/**
* A ZTest[R, E] is an effectfully produced test that requires an R and
* may fail with an E.
*/
type ZTest[-R, +E] = ZIO[R, TestFailure[E], TestSuccess]
object ZTest {
/**
* Builds a test with an effectual assertion
* @param label - Test label for error reporting
* @param assertion - Effectful computation producing TestResult
* @return ZIO effect representing the test
*/
def apply[R, E](label: String, assertion: => ZIO[R, E, TestResult])(implicit
trace: Trace
): ZIO[R, TestFailure[E], TestSuccess]
}Abstract base classes for creating test specifications with different environment requirements.
/**
* Default ZIO spec using standard TestEnvironment
*/
abstract class ZIOSpecDefault extends ZIOSpec[TestEnvironment] {
final type Env = TestEnvironment
}
/**
* ZIO spec with custom environment type R
*/
abstract class ZIOSpec[R] extends ZIOSpecAbstract[R] {
type Env = R
/** The test specification to run */
def spec: Spec[R, Any]
}
/**
* Abstract base class for all ZIO test specifications
*/
abstract class ZIOSpecAbstract[R] {
/** Layer that provides the test environment */
def bootstrap: ZLayer[Any, Any, R] = ZLayer.environment[R]
/** Test execution aspects to apply */
def aspects: Chunk[TestAspectAtLeastR[R]] = Chunk.empty
}Usage Examples:
import zio.test._
// Using ZIOSpecDefault for simple tests
object SimpleTest extends ZIOSpecDefault {
def spec = suite("Simple Tests")(
test("basic") {
assertTrue(1 + 1 == 2)
}
)
}
// Using ZIOSpec with custom environment
trait MyService {
def getValue: UIO[Int]
}
object CustomTest extends ZIOSpec[MyService] {
def spec = suite("Custom Environment Tests")(
test("service test") {
for {
service <- ZIO.service[MyService]
value <- service.getValue
} yield assertTrue(value > 0)
}
)
override def bootstrap = ZLayer.succeed(new MyService {
def getValue = ZIO.succeed(42)
})
}Types representing the outcomes of test execution.
/**
* Represents successful test execution
*/
sealed trait TestSuccess
object TestSuccess {
final case class Succeeded(annotations: TestAnnotationMap = TestAnnotationMap.empty) extends TestSuccess
final case class Ignored(annotations: TestAnnotationMap = TestAnnotationMap.empty) extends TestSuccess
}
/**
* Represents failed test execution
*/
sealed trait TestFailure[+E]
object TestFailure {
final case class Assertion(result: TestResult) extends TestFailure[Nothing]
final case class Runtime[E](cause: Cause[E]) extends TestFailure[E]
}
/**
* Result of test assertion evaluation
*/
case class TestResult(arrow: TestArrow[Any, Boolean]) {
/** Whether the assertion succeeded */
def isSuccess: Boolean
/** Whether the assertion failed */
def isFailure: Boolean
/** 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
}Helper functions for test creation and management.
/**
* Creates a failed test result with the specified runtime cause
*/
def failed[E](cause: Cause[E])(implicit trace: Trace): ZIO[Any, TestFailure[E], Nothing]
/**
* Creates an ignored test result
*/
val ignored: UIO[TestSuccess]
/**
* Passes platform specific information to create a test
*/
def platformSpecific[R, E, A](js: => A, jvm: => A)(f: A => ZTest[R, E]): ZTest[R, E]
/**
* Passes version specific information to create a test
*/
def versionSpecific[R, E, A](scala3: => A, scala2: => A)(f: A => ZTest[R, E]): ZTest[R, E]
/**
* Provides an effect with the "real" environment as opposed to the test environment
*/
def live[R, E, A](zio: ZIO[R, E, A])(implicit trace: Trace): ZIO[R, E, A]