Testing
Effect programs are values that describe work, so testing them is mostly a
matter of running those values and asserting on the result. The @effect/vitest
package wires Effect into Vitest so a test can simply
return an Effect, and the surrounding machinery runs it, fails the test on an
unexpected error, and tears down any scoped resources for you.
Because Effect models time, services, and randomness as data rather than calling
into the platform directly, tests can be fully deterministic. Sleeps,
timeouts, retries, and schedules are driven by a controllable TestClock
instead of real wall-clock time, and the services your code depends on are
swapped for in-memory test implementations through Layer.
import { assert, describe, it } from "@effect/vitest"import { Effect } from "effect"
// A test is just an Effect. `it.effect` runs it and provides the test// services (TestClock, TestConsole) automatically.describe("greeting", () => { it.effect("uppercases the name", () => Effect.gen(function*() { const result = "ada".toUpperCase() assert.strictEqual(result, "ADA") }))})What’s in this section
Section titled “What’s in this section”- Writing tests — use
it.effectto run Effects, assert on results and failures, and parameterize tests witheachand property-based testing. - TestClock — drive sleeps, timeouts, retries, and schedules forward in virtual time so time-dependent code runs instantly and deterministically.
- Testing services — provide test
implementations of your services as layers, share a
layer across a block with
layer(...), and inspect state through a test ref.
@effect/vitest builds on Vitest. Add both as dev dependencies:
pnpm add -D vitest @effect/vitestThen import the enhanced it (and assert, describe, layer) from
@effect/vitest instead of from vitest directly:
import { assert, describe, it, layer } from "@effect/vitest"This it is the standard Vitest test function extended with Effect-aware
methods. The most important ones:
| Method | Description |
|---|---|
it.effect | Run an Effect with the test services provided (TestClock, TestConsole). |
it.live | Run an Effect against the live runtime — real clock, real console. |
it.effect.each | Run the same Effect test over a table of cases. |
it.effect.prop | Property-based testing: generate inputs from Schema arbitraries. |
it.flakyTest | Retry an Effect until it succeeds (or a timeout elapses). |
layer(...) | Build a layer once and share its services across every test in a block. |
Assertions come from the same import: the assert namespace re-exports
Vitest’s assert (assert.strictEqual, assert.deepStrictEqual,
assert.isTrue, …). Effect-aware helpers for Option, Result, and Exit
(assertSome, assertSuccess, assertExitSuccess, …) live in
@effect/vitest/utils.