Overview
Effect provides first-class testing support through the@effect/vitest package. This integration makes it easy to test Effect programs with:
- it.effect: Write tests using Effect.gen syntax
- TestClock: Control time for testing scheduled operations
- Layer testing: Share service layers across tests
- Property-based testing: Generate test cases with Schema
Installation
Install the testing package:Basic Tests with it.effect
Writing Your First Test
Useit.effect instead of regular it to test Effect code:
Parameterized Tests
Test multiple cases withit.effect.each:
Controlling Time with TestClock
TheTestClock service lets you control virtual time in tests:
- Scheduled operations
- Retry logic with delays
- Timeout behavior
- Rate limiting
Testing with Real Runtime Services
Useit.live when you need real runtime services (like actual time):
Property-Based Testing
Generate test cases automatically using Schema arbitraries:Testing Services with Layers
Creating Test Services
Define test-specific implementations using test refs:Testing with Shared Layers
Uselayer(...) to create one shared layer for multiple tests:
layer(...) function:
- Creates the layer once before all tests
- Shares it across all tests in the block
- Tears it down in
afterAll
Testing Higher-Level Services
Test services that depend on other services:Test Patterns
Testing Error Handling
Testing Retry Logic
Testing Concurrent Operations
Best Practices
- Use it.effect for Effect code: Always use
it.effectwhen testing Effect programs - Use TestClock for time-based tests: Don’t use real delays in tests
- Share layers with layer(…): Avoid recreating services for each test
- Create test-specific layers: Use
layerTestfor test implementations - Use property-based testing: Catch edge cases with generated inputs
- Test error cases: Use
Effect.exitto test failure scenarios - Mock external dependencies: Replace real services with test implementations
- Test at the right level: Test business logic through service interfaces
Running Tests
Assertion Helpers
Theassert object from @effect/vitest provides:
assert.strictEqual(actual, expected)assert.deepStrictEqual(actual, expected)assert.isTrue(value)assert.isFalse(value)assert.instanceOf(value, Class)assert.throws(() => code)assert.rejects(async () => code)