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

encore-go-testing — скилл для Claude Code: тесты и установка

Скилл помогает писать и запускать тесты для Encore Go через encore test и стандартный пакет testing. Пригодится для API, сервисов, БД и ошибок.

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

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

Скилл ориентирован на тесты Encore Go: он подсказывает запуск encore test ./..., тестирование отдельного пакета и подробный вывод через -v. Обработчики вызываются напрямую из *_test.go, а проверки строятся на testing.T. Есть примеры для параметров запросов, ошибок Encore, межсервисных вызовов и публикации событий.

В материалах также разобраны операции с базой, тесты cron-логики, табличные сценарии и вложенные тесты через t.Run. Для очистки данных используется sqldb.Exec, а ошибки проверяются через errs.Error. encore test автоматически поднимает тестовые базы, изолирует инфраструктуру для тестов и учитывает зависимости сервисов, поэтому запуск через обычный go test здесь не является рекомендуемым вариантом.

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

  • написать тест для Encore Go-обработчика
  • проверить ответ API с параметрами
  • протестировать операции с базой данных
  • проверить ошибку NotFound
  • разбить проверки на табличные и вложенные тесты

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

  • Напиши *_test.go для обработчика GetUser и проверь ответ для ID 123.
  • Добавь тест создания пользователя: запиши данные, получи запись и сравни её email.
  • Запусти тесты Encore для всех пакетов с подробным выводом через encore test -v ./....

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

1Через Skills CLI (Vercel)

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

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

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

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

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

Вопросы о encore-go-testing

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

Выполните npx skills add encoredev/skills --skill encore-go-testing -a claude-code, затем проверьте файл ~/.claude/skills/go-testing/SKILL.md.

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

Скилл помогает писать и запускать тесты Encore Go с encore test и стандартным пакетом testing. Он охватывает прямой вызов обработчиков, базы, ошибки, события и cron-логику.

Почему для Encore Go советуют encore test, а не go test?

encore test автоматически поднимает тестовые базы, изолирует инфраструктуру для тестов и обрабатывает зависимости сервисов.

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

SKILL.md · Apache-2.0
---
name: encore-go-testing
description: Write or run automated tests for Encore Go code with `encore test` and the standard library `testing` package. Covers isolated per-test databases, calling handlers directly, and `*testing.T` patterns.
when_to_use: >-
  User wants to add/write/fix a test in Go, write a `*_test.go` file, test an endpoint or service, set up `encore test`, configure isolated test databases, write `t.Cleanup`/`t.Helper` for db cleanup, mock external dependencies, or assert on API request/response behaviour. Trigger phrases: "write a Go test", "add tests for", "go test", "encore test", "test the endpoint", "test the service", "integration test", "isolated database".
---

# Testing Encore Go Applications

## Instructions

Encore Go uses standard Go testing with `encore test`.

### Run Tests

```bash
# Run all tests with Encore (recommended)
encore test ./...

# Run tests for a specific package
encore test ./user/...

# Run with verbose output
encore test -v ./...
```

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

### Test an API Endpoint

```go
// hello/hello_test.go
package hello

import (
    "context"
    "testing"
)

func TestHello(t *testing.T) {
    ctx := context.Background()
    
    resp, err := Hello(ctx)
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
    
    if resp.Message != "Hello, World!" {
        t.Errorf("expected 'Hello, World!', got '%s'", resp.Message)
    }
}
```

### Test with Request Parameters

```go
// user/user_test.go
package user

import (
    "context"
    "testing"
)

func TestGetUser(t *testing.T) {
    ctx := context.Background()
    
    user, err := GetUser(ctx, &GetUserParams{ID: "123"})
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
    
    if user.ID != "123" {
        t.Errorf("expected ID '123', got '%s'", user.ID)
    }
}
```

### Test Database Operations

Encore provides isolated test databases:

```go
// user/user_test.go
package user

import (
    "context"
    "testing"
    
    "encore.dev/storage/sqldb"
)

func TestCreateUser(t *testing.T) {
    ctx := context.Background()
    
    // Clean up
    _, _ = sqldb.Exec(ctx, db, "DELETE FROM users")
    
    // Create user
    created, err := CreateUser(ctx, &CreateUserParams{
        Email: "[email protected]",
        Name:  "Test User",
    })
    if err != nil {
        t.Fatalf("failed to create user: %v", err)
    }
    
    // Retrieve and verify
    retrieved, err := GetUser(ctx, &GetUserParams{ID: created.ID})
    if err != nil {
        t.Fatalf("failed to get user: %v", err)
    }
    
    if retrieved.Email != "[email protected]" {
        t.Errorf("expected email '[email protected]', got '%s'", retrieved.Email)
    }
}
```

### Test Service-to-Service Calls

```go
// order/order_test.go
package order

import (
    "context"
    "testing"
)

func TestCreateOrder(t *testing.T) {
    ctx := context.Background()
    
    // Service calls work normally in tests
    order, err := CreateOrder(ctx, &CreateOrderParams{
        UserID: "user-123",
        Items: []OrderItem{
            {ProductID: "prod-1", Quantity: 2},
        },
    })
    if err != nil {
        t.Fatalf("failed to create order: %v", err)
    }
    
    if order.Status != "pending" {
        t.Errorf("expected status 'pending', got '%s'", order.Status)
    }
}
```

### Test Error Cases

```go
package user

import (
    "context"
    "errors"
    "testing"
    
    "encore.dev/beta/errs"
)

func TestGetUser_NotFound(t *testing.T) {
    ctx := context.Background()
    
    _, err := GetUser(ctx, &GetUserParams{ID: "nonexistent"})
    if err == nil {
        t.Fatal("expected error, got nil")
    }
    
    // Check error code
    var e *errs.Error
    if errors.As(err, &e) {
        if e.Code != errs.NotFound {
            t.Errorf("expected NotFound, got %v", e.Code)
        }
    } else {
        t.Errorf("expected errs.Error, got %T", err)
    }
}
```

### Test Pub/Sub

```go
// notifications/notifications_test.go
package notifications

import (
    "context"
    "testing"
    
    "myapp/events"
)

func TestPublishOrderCreated(t *testing.T) {
    ctx := context.Background()
    
    msgID, err := events.OrderCreated.Publish(ctx, &events.OrderCreatedEvent{
        OrderID: "order-123",
        UserID:  "user-456",
        Total:   9999,
    })
    if err != nil {
        t.Fatalf("failed to publish: %v", err)
    }
    
    if msgID == "" {
        t.Error("expected message ID, got empty string")
    }
}
```

### Test Cron Jobs

Test the underlying function, not the cron schedule:

```go
// cleanup/cleanup_test.go
package cleanup

import (
    "context"
    "testing"
)

func TestCleanupExpiredSessions(t *testing.T) {
    ctx := context.Background()
    
    // Create some expired sessions first
    createExpiredSession(ctx)
    
    // Call the endpoint directly
    err := CleanupExpiredSessions(ctx)
    if err != nil {
        t.Fatalf("cleanup failed: %v", err)
    }
    
    // Verify cleanup happened
    count := countSessions(ctx)
    if count != 0 {
        t.Errorf("expected 0 sessions, got %d", count)
    }
}
```

### Table-Driven Tests

```go
func TestValidateEmail(t *testing.T) {
    tests := []struct {
        name    string
        email   string
        wantErr bool
    }{
        {"valid email", "[email protected]", false},
        {"missing @", "userexample.com", true},
        {"empty", "", true},
        {"valid with subdomain", "[email protected]", false},
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            err := validateEmail(tt.email)
            if (err != nil) != tt.wantErr {
                t.Errorf("validateEmail(%q) error = %v, wantErr %v", tt.email, err, tt.wantErr)
            }
        })
    }
}
```

### Test with Subtests

```go
func TestUserCRUD(t *testing.T) {
    ctx := context.Background()
    var userID string
    
    t.Run("create", func(t *testing.T) {
        user, err := CreateUser(ctx, &CreateUserParams{
            Email: "[email protected]",
            Name:  "Test",
        })
        if err != nil {
            t.Fatalf("create failed: %v", err)
        }
        userID = user.ID
    })
    
    t.Run("read", func(t *testing.T) {
        user, err := GetUser(ctx, &GetUserParams{ID: userID})
        if err != nil {
            t.Fatalf("read failed: %v", err)
        }
        if user.Email != "[email protected]" {
            t.Errorf("wrong email: %s", user.Email)
        }
    })
    
    t.Run("delete", func(t *testing.T) {
        err := DeleteUser(ctx, &DeleteUserParams{ID: userID})
        if err != nil {
            t.Fatalf("delete failed: %v", err)
        }
    })
}
```

### Test Database Isolation

Create isolated, fully-migrated test databases using `et.NewTestDatabase()`:

```go
import "encore.dev/et"

func TestWithFreshDatabase(t *testing.T) {
    // Creates a new database with all migrations applied
    testDB := et.NewTestDatabase(t, db)

    // Use testDB for queries - it's completely isolated
    _, err := testDB.Exec(ctx, "INSERT INTO users (email) VALUES ($1)", "[email protected]")
    if err != nil {
        t.Fatal(err)
    }
}
```

### Service Instance Isolation

By default, service structs are shared across tests for performance. Enable isolation when tests modify service state:

```go
import "encore.dev/et"

func TestWithServiceIsolation(t *testing.T) {
    // Enable service instance isolation for this test
    et.EnableServiceInstanceIsolation()

    // Now this test gets its own service struct instance
    // preventing state interference with other tests
}
```

### Test Tracing Dashboard

View test execution traces in the development dashboard at `http://localhost:9400` while tests run. This helps diagnose failures by showing:
- Request/response data
- Database queries
- Service-to-service calls
- Errors and stack traces

### Mocking Endpoints and Services

Mock endpoints or entire services for isolated unit testing:

```go
import "encore.dev/et"

func TestWithMockedEndpoint(t *testing.T) {
    // Mock a specific endpoint
    et.MockEndpoint(products.GetPrice, func(ctx context.Context, p *products.PriceParams) (*products.PriceResponse, error) {
        return &products.PriceResponse{Price: 100}, nil
    })

    // Mock an entire service
    et.MockService("products", &mockProductService{})
}
```

### Guidelines

- Use `encore test` to run tests with infrastructure setup
- Each test gets access to real infrastructure (databases, Pub/Sub)
- Test API endpoints by calling them directly as functions
- Service-to-service calls work normally in tests
- Use table-driven tests for testing multiple cases
- Use `et.NewTestDatabase()` for isolated database testing
- Use `et.EnableServiceInstanceIsolation()` when tests modify service state
- Don't mock Encore infrastructure - use the real thing
- Mock external dependencies (third-party APIs, email services, etc.)

© encoredev · Apache-2.0 · encoredev/skills

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

Все скиллы по теме «Тесты и QA» →
improve-codebase-architecture Matt Pocock Скилл ищет архитектурные узкие места в кодовой базе и показывает варианты углубления модулей в HTML-отчёте. Подойдёт для ревью перед рефакторингом. 1 163 035установок design-taste-frontend Leonxlnx Скилл задаёт арт-дирекцию для публичных страниц и рабочих экранов, а затем проверяет результат в браузере по скриншотам. Нужен, когда интерфейс выглядит шаблонным или недоработанным. CX Codex +1 678 700установок tdd Matt Pocock Скилл управляет циклом красный-зелёный в TDD: проверяет, что тесты пишутся до кода, держит их на уровне публичных интерфейсов и не завязывает на внутреннюю структуру. 1 141 062установок skill-creator официальный anthropics Помогает создать новый скилл, доработать существующий и проверить результат через тестовые промпты и оценки. 414 180установок agent-browser vercel-labs Скилл управляет браузером через CLI: открывает страницы, заполняет формы, нажимает кнопки и проверяет веб-приложения. Подходит для задач, где агенту нужно действовать в интерфейсе. CX Codex +1 1 200 000установок prototype Matt Pocock Создаёт временный прототип, чтобы проверить логику, модель состояния или вид интерфейса до работы над основным кодом. 986 201установок

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

encore-testing Помогает писать и запускать автотесты для Encore.ts через encore test и vitest или jest. Пригодится, когда нужно покрыть эндпоинт или сервис и не возиться с изолированными базами вручную. CX Codex +1 791установок encore-frontend Скилл связывает фронтенд на React, Next.js, Vue или Svelte с бэкендом Encore.ts: генерация типизированного клиента, CORS и токены авторизации. CX Codex +1 763установок encore-migrate Пошагово переносит бэкенд на Encore.ts или Encore Go. Создаёт план в migration-plan.md, инвентаризирует эндпоинты, базы и очереди, разделяя серверную логику и фронтенд. CX Codex +1 725установок encore-go-auth Скилл помогает защищать Go-эндпоинты Encore и проверять, кто выполняет запрос. Пригодится для JWT, API-ключей и сессионных cookie. CX Codex +1 557установок encore-go-service Скилл помогает создавать сервисы Encore.go, раскладывать Go-пакеты и вызывать один сервис из другого. Пригодится для новых и уже спроектированных приложений. CX Codex +1 555установок encore-go-api Помогает агенту писать эндпоинты Encore Go с аннотацией //encore:api: типизированные структуры запроса и ответа, параметры пути, query, заголовки и cookie, коды ошибок. CX Codex +1 555установок encore-go-database Помогает создавать таблицы PostgreSQL, писать миграции и выполнять SQL-запросы в сервисах на Encore Go через пакет sqldb. CX Codex +1 553установок encore-go-code-review Скилл проверяет Go-код на Encore: инфраструктура внутри функций, забытый context, SQL-инъекции и другие анти-паттерны перед мержем. CX Codex +1 553установок

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

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