Zeno

Unit Testing

Unit testing with Vitest

Zeno uses Vitest for fast, modern unit testing with native TypeScript support.

Setup

Tests use the shared config from @zeno-lib/vitest:

// vitest.config.ts
import { loadEnv } from "vite"
import tsconfigPaths from "vite-tsconfig-paths"
import { defineConfig } from "vitest/config"

export default defineConfig({
  plugins: [tsconfigPaths()],
  test: {
    env: loadEnv("test", process.cwd(), ""),
  },
})

Writing Tests

import { describe, expect, test } from "vitest"

describe("Calculator", () => {
  test("adds two numbers", () => {
    expect(1 + 2).toBe(3)
  })

  test("handles edge cases", () => {
    expect(0 + 0).toBe(0)
    expect(-1 + 1).toBe(0)
  })
})

Commands

# Run tests once
pnpm test

# Watch mode
pnpm test:watch

# Run for specific package
pnpm turbo run test --filter @zeno-lib/example

Testing React Components

Use @testing-library/react (included in @zeno-lib/vitest):

import { render, screen } from "@testing-library/react"
import { describe, expect, test } from "vitest"
import { Button } from "@zeno-lib/ui/button"

describe("Button", () => {
  test("renders with text", () => {
    render(<Button>Click me</Button>)
    expect(screen.getByRole("button")).toHaveTextContent("Click me")
  })
})

Mocking

import { vi, describe, expect, test } from "vitest"

const mockFetch = vi.fn()

describe("API", () => {
  test("fetches data", async () => {
    mockFetch.mockResolvedValue({ data: "test" })
    const result = await mockFetch()
    expect(result.data).toBe("test")
  })
})

Environment Variables

Tests run with NODE_ENV=test. Load env vars in your config:

test: {
  env: loadEnv("test", process.cwd(), ""),
}

Create a .env.test file for test-specific variables.

Best Practices

  • Write assertions inside test() blocks
  • Use async/await instead of done callbacks
  • Don't commit .only or .skip
  • Keep tests focused and independent
  • Use descriptive test names