# How Tests Are Organized in the usekaneo/kaneo Repository

> Discover how tests are organized in the usekaneo/kaneo repository. Learn about fast unit tests and full-stack integration tests structured under tests/api and tests/api-integration.

- Repository: [kaneo.app/kaneo](https://github.com/usekaneo/kaneo)
- Tags: how-to-guide
- Published: 2026-08-04

---

**Tests in the Kaneo repository are organized into two top-level scopes under `tests/`: `tests/api/` for fast unit tests and `tests/api-integration/` for full-stack integration tests, with feature-specific subfolders mirroring the source layout.**

The **usekaneo/kaneo** project is an open-source platform built with a monorepo structure. Understanding how tests are organized in this repository helps contributors locate existing tests and follow established patterns when adding new functionality. This guide breaks down the directory structure, test runner configuration, and naming conventions based on the actual source code.

## Test Directory Structure

All test files live under the top-level **`tests/`** directory. The organization follows a clear separation between isolated unit tests and end-to-end integration tests.

### API Unit Tests: `tests/api/`

The **`tests/api/`** directory contains fast, isolated tests that exercise individual utilities, helpers, and lightweight API logic without spinning up the full server or database.

- **Location pattern:** `tests/api/{feature}/...` mirrors the source structure in `apps/api/src/`
- **Example files:**
  - [`tests/api/utils/verify-turnstile.test.ts`](https://github.com/usekaneo/kaneo/blob/main/tests/api/utils/verify-turnstile.test.ts) — unit tests for the Turnstile verification helper
  - [`tests/api/ws/broadcast.test.ts`](https://github.com/usekaneo/kaneo/blob/main/tests/api/ws/broadcast.test.ts) — WebSocket broadcast logic

### API Integration Tests: `tests/api-integration/`

The **`tests/api-integration/`** directory holds end-to-end tests that start the full API server, run database migrations, and exercise real HTTP routes.

- **Location pattern:** `tests/api-integration/{feature}/...`
- **Example files:**
  - [`tests/api-integration/task.test.ts`](https://github.com/usekaneo/kaneo/blob/main/tests/api-integration/task.test.ts) — full task CRUD flow
  - [`tests/api-integration/openapi.test.ts`](https://github.com/usekaneo/kaneo/blob/main/tests/api-integration/openapi.test.ts) — OpenAPI spec validation

### Test Helpers: `tests/api-integration/helpers/`

Reusable test utilities live under `tests/api-integration/helpers/`. These include fixtures, database helpers, and authentication mocks that provide consistent setup and teardown across integration suites.

## Feature-Specific Subfolders

Each logical feature gets its own subdirectory inside the appropriate test scope. This mirroring makes it easy to locate the test corresponding to any source file.

Common feature folders include:

- `utils/` — utility function tests
- `ws/` — WebSocket-related tests
- `redis/` — caching layer tests
- `plugins/github/` — GitHub integration tests
- `billing/` — subscription and payment tests

## Test Runner and Configuration

**Vitest** powers the test runner for both the API and Web packages. Separate configuration files ensure correct TypeScript paths and environment variables for each package.

### Configuration Files

| File | Purpose |
|------|---------|
| [`apps/api/vitest.config.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/vitest.config.ts) | API package configuration (tsconfig paths, globals, coverage) |
| [`apps/web/vitest.config.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/web/vitest.config.ts) | Web client configuration (React testing environment) |

### Running Tests

```bash

# Run all tests

pnpm test

# Run integration tests specifically

pnpm test:integration

```

Vitest automatically discovers all `*.test.ts` files under `tests/` and applies the appropriate configuration based on the package being exercised.

## Code Examples

### Unit Test Structure

This example from [`tests/api/utils/verify-turnstile.test.ts`](https://github.com/usekaneo/kaneo/blob/main/tests/api/utils/verify-turnstile.test.ts) shows the typical pattern for API unit tests:

```typescript
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { verifyTurnstile } from "../../../apps/api/src/utils/verify-turnstile";

describe("verifyTurnstile", () => {
  beforeEach(() => {
    process.env.TURNSTILE_SECRET_KEY = "test-secret";
  });

  afterEach(() => {
    vi.restoreAllMocks();
  });

  it("posts the secret, token, and remoteip to Cloudflare", async () => {
    const fetchMock = vi.fn().mockResolvedValue({
      json: async () => ({ success: true }),
    });
    globalThis.fetch = fetchMock as unknown as typeof fetch;

    const result = await verifyTurnstile("good-token", "203.0.113.7");
    expect(result.ok).toBe(true);
    expect(fetchMock).toHaveBeenCalledOnce();
  });
});

```

### Integration Test Structure

This example from [`tests/api-integration/task.test.ts`](https://github.com/usekaneo/kaneo/blob/main/tests/api-integration/task.test.ts) demonstrates a full end-to-end flow using helper utilities:

```typescript
import { describe, it, expect } from "vitest";
import { apiClient } from "./helpers/fixtures";

describe("Task API", () => {
  it("creates, reads, updates and deletes a task", async () => {
    const created = await apiClient.post("/tasks", { title: "Demo" });
    expect(created.status).toBe(201);

    const fetched = await apiClient.get(`/tasks/${created.body.id}`);
    expect(fetched.body.title).toBe("Demo");

    await apiClient.patch(`/tasks/${created.body.id}`, { title: "Edited" });
    const updated = await apiClient.get(`/tasks/${created.body.id}`);
    expect(updated.body.title).toBe("Edited");

    await apiClient.delete(`/tasks/${created.body.id}`);
    const deleted = await apiClient.get(`/tasks/${created.body.id}`);
    expect(deleted.status).toBe(404);
  });
});

```

## Key Files and Their Purposes

| File | Purpose |
|------|---------|
| [`tests/api/utils/verify-turnstile.test.ts`](https://github.com/usekaneo/kaneo/blob/main/tests/api/utils/verify-turnstile.test.ts) | Unit test template showing Vitest patterns with mocking |
| [`tests/api-integration/task.test.ts`](https://github.com/usekaneo/kaneo/blob/main/tests/api-integration/task.test.ts) | Integration test exercising complete REST endpoint flows |
| [`apps/api/vitest.config.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/vitest.config.ts) | API-specific Vitest configuration |
| [`apps/web/vitest.config.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/web/vitest.config.ts) | Web client Vitest configuration |
| `tests/api-integration/helpers/` | Shared fixtures and database utilities |

## CI Pipeline Benefits

The separation between unit and integration tests enables optimized CI workflows:

1. **Fast feedback** — unit tests run quickly in the main pipeline
2. **Full coverage** — heavier integration suite runs in a dedicated step
3. **Parallel execution** — different test scopes can execute on separate runners

## Summary

- **Two top-level scopes:** `tests/api/` for unit tests, `tests/api-integration/` for integration tests
- **Feature mirroring:** subfolders match the source tree structure for easy navigation
- **Vitest runner:** separate configs at [`apps/api/vitest.config.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/vitest.config.ts) and [`apps/web/vitest.config.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/web/vitest.config.ts)
- **Helper utilities:** centralized in `tests/api-integration/helpers/` for reuse
- **Naming convention:** all test files use `*.test.ts` suffix

## Frequently Asked Questions

### Where should I add a new test in the Kaneo repository?

Add unit tests for isolated logic in `tests/api/{feature}/` and full-stack tests in `tests/api-integration/{feature}/`. Mirror the source file path under `apps/api/src/` to keep tests discoverable.

### How do I run only the unit tests without starting the database?

Run `pnpm test` from the API package directory or use Vitest's file pattern filtering. Unit tests in `tests/api/` are designed to run without external dependencies.

### What testing utilities are available for integration tests?

The `tests/api-integration/helpers/` directory contains reusable fixtures including `apiClient` for HTTP requests, database seeding utilities, and authentication mocks. Import these in your integration test files to ensure consistent setup.

### Does the Web client have its own test configuration?

Yes. The Web client uses [`apps/web/vitest.config.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/web/vitest.config.ts) with React Testing Library configured, separate from the API's configuration. This allows proper testing of React components with the appropriate environment setup.