Testing
The Problem
Traditional test environments suffer from state pollution:
- Tests affect each other through shared database state
- File system changes persist between runs
- Flaky tests due to execution ordering
The Iris Solution
Keep one seeded base sandbox alive. Each test forks from it — fully isolated, zero setup overhead per test.
import { Sandbox } from '@iris/sdk'import { describe, it, beforeAll, afterAll, afterEach } from 'vitest'
let base: Sandbox
beforeAll(async () => { base = await Sandbox.create()
// Install deps, seed database, etc. await base.exec.run('npm install') await base.exec.run('npm run db:seed')})
afterAll(async () => { await base.kill()})
describe('User API', () => { let env: Sandbox
beforeEach(async () => { // Each test starts from the same clean state env = await base.fork() })
afterEach(async () => { await env.kill() })
it('creates a user', async () => { const result = await env.exec.run('npm test -- user.create.test.ts') expect(result.exit_code).toBe(0) })
it('deletes a user', async () => { const result = await env.exec.run('npm test -- user.delete.test.ts') expect(result.exit_code).toBe(0) })})Parallel Test Execution
Fork from the same base in parallel — no interference:
const tests = [ 'auth.test.ts', 'users.test.ts', 'payments.test.ts', 'notifications.test.ts',]
const results = await Promise.all( tests.map(async (test) => { const env = await base.fork() const result = await env.exec.run(`npm test -- ${test}`) await env.kill() return { test, passed: result.exit_code === 0, output: result.stdout } }),)
const failed = results.filter((r) => !r.passed)if (failed.length > 0) { console.error('Failed:', failed.map((r) => r.test))}Integration Testing
Test against real services with a guaranteed-clean environment per suite:
async function integrationTest() { const base = await Sandbox.create()
// Start services once await base.exec.run('docker-compose up -d') await base.exec.run('python3 wait_for_services.py')
// Each suite gets a fresh fork — database is in the same state for all await Promise.all( testSuites.map(async (suite) => { const env = await base.fork() try { const result = await env.exec.run(`pytest ${suite}`) if (!result.ok) console.error(suite, result.stderr) } finally { await env.kill() } }), )
await base.kill()}CI/CD Integration
GitHub Actions
name: Tests
on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Install SDK run: npm install @iris/sdk
- name: Run Tests env: IRIS_API_KEY: ${{ secrets.IRIS_API_KEY }} run: npm testPerformance Comparison
| Approach | Setup Time | Per-Test Overhead |
|---|---|---|
| Docker | 30-60s | 5-10s |
| VM Snapshot | 10-30s | 2-5s |
| Iris Fork | Once | <1ms |