К основному содержанию
скилл CX Codex

encore-testing — скилл для Claude Code: тесты Encore.ts

Помогает писать и запускать автотесты для Encore.ts через encore test и vitest или jest. Пригодится, когда нужно покрыть эндпоинт или сервис и не возиться с изолированными базами вручную.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add encoredev/skills --skill encore-testing -a claude-code
npx skills add encoredev/skills --skill testing -a claude-code
Открыть на GitHub

Что делает encore-testing

Скилл описывает, как тестировать приложения на Encore.ts обычными инструментами TypeScript. Рекомендованная связка — Vitest: npm install -D vitest, скрипт test в package.json, запуск через encore test. Именно encore test поднимает тестовые базы и разводит инфраструктуру по тестам, поэтому он и стоит первым в примерах.

Внутри разобраны типовые сценарии: вызов хендлера напрямую с параметрами, проверка ошибок через APIError и код not_found, работа с базой в beforeEach и очистка таблиц, сервис-сервис вызовы, публикация событий и тесты cron-задач (там тестируется сама функция, а не расписание). Для ~encore импортов нужен vite.config.ts с алиасом на ./encore.gen.

Отдельный момент про авторизацию. Мок getAuthData работает только в том коде, который читает его напрямую в процессе теста. Вызовы через ~encore/clients идут через рантайм Encore, мок он не видит, и эндпоинт с auth: true упадёт с ошибкой про отсутствующую авторизацию. В этом случае данные авторизации передают явно вторым аргументом. Если гоняете тесты в VS Code, файловый параллелизм советуют отключить — иначе конфликтуют порты.

Какие задачи решает

  • написать первый тест для эндпоинта Encore.ts
  • настроить encore test и vitest в проекте
  • поднять изолированную базу под каждый тест
  • проверить ответ и код ошибки APIError
  • протестировать эндпоинт с auth: true без реального логина

Примеры запросов агенту

  • напиши vitest-тест для эндпоинта getUser с параметром id
  • настрой encore test и очистку таблицы users в beforeEach
  • протестируй эндпоинт с auth: true, передав authData явно

Как установить encore-testing

1Через Skills CLI (Vercel)

npx skills add encoredev/skills --skill encore-testing -a claude-code
npx skills add encoredev/skills --skill testing -a claude-code

2Вручную: положить файлы

~/.claude/skills/testing/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/testing/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о encore-testing

Как установить encore-testing в Claude?

Через skills CLI: npx skills add encoredev/skills --skill encore-testing -a claude-code. После установки файл скилла лежит в ~/.claude/skills/testing/SKILL.md.

Что делает encore-testing?

Подсказывает агенту, как писать и запускать тесты для Encore.ts: вызов хендлеров напрямую, изолированные базы, моки внешних сервисов, проверка ошибок и авторизации.

Почему мок getAuthData не работает через ~encore/clients?

Такие вызовы идут через рантайм Encore, который мок не видит, и эндпоинт с auth: true падает. Данные авторизации передавайте явно: await user.follow({ username: "jake" }, { authData: { userID: "123" } }).

Исходный текст

SKILL.md · Apache-2.0
---
name: encore-testing
description: Write or run automated tests for Encore.ts code with `encore test` and vitest/jest. Covers isolated per-test databases, calling handlers directly, and `describe`/`it`/`expect`.
when_to_use: >-
  User wants to add/write/fix a test, write a vitest or jest spec, test an endpoint or service, set up `encore test`, configure isolated test databases, write `beforeEach`/`afterEach` for db cleanup, mock external dependencies, or assert on API request/response behaviour. Trigger phrases: "write a test", "write a vitest test", "add tests for", "vitest", "jest", "encore test", "test the endpoint", "test the service", "integration test", "isolated database".
---

# Testing Encore.ts Applications

## Instructions

Encore.ts uses standard TypeScript testing tools. The recommended setup is Vitest.

### Setup Vitest

```bash
npm install -D vitest
```

Add to `package.json`:

```json
{
  "scripts": {
    "test": "vitest"
  }
}
```

### Test an API Endpoint

```typescript
// api.test.ts
import { describe, it, expect } from "vitest";
import { hello } from "./api";

describe("hello endpoint", () => {
  it("returns a greeting", async () => {
    const response = await hello();
    expect(response.message).toBe("Hello, World!");
  });
});
```

### Run Tests

```bash
# Run with Encore (recommended - sets up infrastructure)
encore test

# Or run directly with npm
npm test
```

Using `encore test` is recommended because it:
- Sets up test databases automatically
- Provides isolated infrastructure per test
- Handles service dependencies

### Test with Request Parameters

```typescript
// api.test.ts
import { describe, it, expect } from "vitest";
import { getUser } from "./api";

describe("getUser endpoint", () => {
  it("returns the user by ID", async () => {
    const user = await getUser({ id: "123" });
    expect(user.id).toBe("123");
    expect(user.name).toBeDefined();
  });
});
```

### Test Database Operations

Encore provides isolated test databases:

```typescript
// user.test.ts
import { describe, it, expect, beforeEach } from "vitest";
import { createUser, getUser, db } from "./user";

describe("user operations", () => {
  beforeEach(async () => {
    // Clean up before each test
    await db.exec`DELETE FROM users`;
  });

  it("creates and retrieves a user", async () => {
    const created = await createUser({ email: "[email protected]", name: "Test" });
    const retrieved = await getUser({ id: created.id });
    
    expect(retrieved.email).toBe("[email protected]");
  });
});
```

### Test Service-to-Service Calls

```typescript
// order.test.ts
import { describe, it, expect } from "vitest";
import { createOrder } from "./order";

describe("order service", () => {
  it("creates an order and notifies user service", async () => {
    // Service calls work normally in tests
    const order = await createOrder({
      userId: "user-123",
      items: [{ productId: "prod-1", quantity: 2 }],
    });
    
    expect(order.id).toBeDefined();
    expect(order.status).toBe("pending");
  });
});
```

### Test Error Cases

```typescript
import { describe, it, expect } from "vitest";
import { getUser } from "./api";
import { APIError } from "encore.dev/api";

describe("error handling", () => {
  it("throws NotFound for missing user", async () => {
    await expect(getUser({ id: "nonexistent" }))
      .rejects
      .toThrow("user not found");
  });

  it("throws with correct error code", async () => {
    try {
      await getUser({ id: "nonexistent" });
    } catch (error) {
      expect(error).toBeInstanceOf(APIError);
      expect((error as APIError).code).toBe("not_found");
    }
  });
});
```

### Test Authenticated Endpoints

Mock `getAuthData` to call `auth: true` endpoints directly as a given user:

```typescript
import { describe, it, expect, vi } from "vitest";
import * as auth from "~encore/auth";
import { getProfile } from "./api";

it("returns the caller's profile", async () => {
  vi.spyOn(auth, "getAuthData").mockImplementation(() => ({ userID: "123" }));
  const profile = await getProfile();
  expect(profile.id).toBe("123");
});
```

The mock only affects code in the test process that reads `getAuthData()` directly. Calls made through `~encore/clients` go through the Encore runtime, which does not see the mock, so an `auth: true` endpoint called that way fails with "endpoint requires auth but none provided". Pass the auth data explicitly instead:

```typescript
import { user } from "~encore/clients";

await user.follow({ username: "jake" }, { authData: { userID: "123" } });
```

### Test Pub/Sub

```typescript
// notifications.test.ts
import { describe, it, expect, vi } from "vitest";
import { orderCreated } from "./events";

describe("pub/sub", () => {
  it("publishes order created event", async () => {
    const messageId = await orderCreated.publish({
      orderId: "order-123",
      userId: "user-456",
      total: 9999,
    });
    
    expect(messageId).toBeDefined();
  });
});
```

### Test Cron Jobs

Test the underlying function, not the cron schedule:

```typescript
// cleanup.test.ts
import { describe, it, expect } from "vitest";
import { cleanupExpiredSessions } from "./cleanup";

describe("cleanup job", () => {
  it("removes expired sessions", async () => {
    // Create some expired sessions first
    await createExpiredSession();
    
    // Call the endpoint directly
    await cleanupExpiredSessions();
    
    // Verify cleanup happened
    const remaining = await countSessions();
    expect(remaining).toBe(0);
  });
});
```

### Mocking External Services

```typescript
import { describe, it, expect, vi, beforeEach } from "vitest";
import { sendWelcomeEmail } from "./email";

// Mock external API
vi.mock("./external-email-client", () => ({
  send: vi.fn().mockResolvedValue({ success: true }),
}));

describe("email service", () => {
  it("sends welcome email", async () => {
    const result = await sendWelcomeEmail({ userId: "123" });
    expect(result.sent).toBe(true);
  });
});
```

### Test Configuration

Create `vite.config.ts` (required for `~encore` imports):

```typescript
import { defineConfig } from "vitest/config";
import path from "path";

export default defineConfig({
  resolve: {
    alias: {
      "~encore": path.resolve(__dirname, "./encore.gen"),
    },
  },
  test: {
    globals: true,
    environment: "node",
    include: ["**/*.test.ts"],
    coverage: {
      reporter: ["text", "json", "html"],
    },
  },
});
```

### VS Code Integration

Install the [Vitest extension](https://marketplace.visualstudio.com/items?itemName=vitest.explorer) and add to `.vscode/settings.json`:

```json
{
  "vitest.commandLine": "encore test"
}
```

**Note:** For VS Code test explorer, disable file-level parallelism to avoid port conflicts:

```typescript
// vite.config.ts
export default defineConfig({
  // ...
  test: {
    fileParallelism: false,  // Disable for VS Code
    // ...
  },
});
```

Re-enable for CI: `encore test --fileParallelism=true`

### Guidelines

- Use `encore test` to run tests with infrastructure setup
- Each test file gets an isolated database transaction (rolled back after)
- Test API endpoints by calling them directly as functions
- Service-to-service calls work normally in tests
- Mock external dependencies (third-party APIs, email services, etc.)
- Don't mock Encore infrastructure (databases, Pub/Sub) - use the real thing

© encoredev · Apache-2.0 · encoredev/skills

Похожие скиллы

Всё по теме «Тесты и QA» →
testing-best-practices agent-skills Набор правил по юнит- и интеграционным тестам и TDD: 34 правила в 7 категориях на TypeScript с Jest и Vitest. Пригодится, когда пишете тесты или разбираете чужие. CX Codex +1 899установок javascript-testing-patterns Seth Hobson Скилл подсказывает, как писать unit-, интеграционные и end-to-end-тесты для JavaScript и TypeScript. Пригодится при настройке тестовой инфраструктуры и работе по TDD. CX Codex 20 472установок unit-testing kindlmann Скилл для написания юнит-тестов: подсказывает, какие тест-двойники брать, как настроить порог покрытия и как проверить тесты мутационным тестированием. CX Codex +1 1 100установок api-test-suite-generator patricio0312rev Скилл сканирует определения маршрутов и генерирует тесты API на Jest, Vitest или Supertest. Пригодится, когда эндпоинты уже есть, а тестов к ним нет. CX Codex +1 303установок vitest-testing secondsky Скилл для написания юнит- и интеграционных тестов на Vitest в проектах на TypeScript и JavaScript. Пригодится, когда нужно быстро настроить конфиг, моки и покрытие. CX Codex +1 1 200установок testing-anti-patterns bobmatnyc Скилл помогает находить ошибки в тестах: проверки поведения моков, тестовые методы в продакшене и неполные заглушки. CX Codex +1 368установок

Из того же набора10

encore-api Помогает агенту писать эндпоинты Encore.ts через api(...): типы запроса и ответа, параметры пути, валидация, ошибки. CX Codex +1 828установок encore-code-review Скилл проверяет код на Encore.ts перед мержем: инфраструктура внутри функций, require() вместо импортов, сырые Error вместо APIError. CX Codex +1 819установок encore-frontend Скилл связывает фронтенд на React, Next.js, Vue или Svelte с бэкендом Encore.ts: генерация типизированного клиента, CORS и токены авторизации. CX Codex +1 763установок encore-go-code-review Скилл проверяет Go-код на Encore: инфраструктура внутри функций, забытый context, SQL-инъекции и другие анти-паттерны перед мержем. CX Codex +1 553установок encore-bucket Учит агента работать с объектным хранилищем Encore.ts: загрузка, скачивание, список и удаление файлов через Bucket. CX Codex +1 419установок encore-webhook Скилл учит агента принимать входящие вебхуки от Stripe, GitHub, Slack и других сервисов через api.raw() и проверять подписи. CX Codex +1 418установок encore-go-secret Скилл учит агента объявлять API-ключи и пароли в Encore Go через структуру secrets и задавать значения по окружениям. CX Codex +1 307установок encore-go-bucket Скилл подсказывает агенту, как объявлять бакеты и работать с файлами в Encore Go: загрузка, выгрузка, подписанные ссылки. CX Codex +1 307установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой