一键导入
go-testing
Go Testing Skill
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Go Testing Skill
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Diagnose Azedarach command latency and daemon/TUI performance with OpenTelemetry traces exported to a local Jaeger backend. Use when investigating slow `az` commands, TUI stalls, daemon RPC latency, missing spans, local Jaeger setup, or trace-driven performance regressions in this repository.
Review and integrate Azedarach issues that are in_review. Use when Codex is asked to run a reviewer/integrator session, sweep active issues that are ready for review, inspect worker evidence and diffs, return actionable findings to live or paused issue sessions, close accepted work, or get in_review issues integrated.
Review, consolidate, test, and harden Azedarach SQLite migrations before integration. Use for any migration, schema ensure/repair logic, trigger or index change, persistence-authority change, migration failure, or pre-merge review of a branch containing database changes. Also use when validating upgrades against real root-user or registered project databases.
Run an iterative code review and fix cycle until findings stabilize. Use when the user asks Codex to review code, review and fix, loop review/fix, address review findings, harden a change before handoff, or keep reviewing until repeated passes find no new actionable issues. Also use proactively before Codex declares coding work done, marks an issue in_review, says a change is ready, or hands off implementation that modified code, tests, build scripts, migrations, config, or developer tooling.
Build and review production-grade Go logging and observability with `log/slog` and OpenTelemetry. Use when adding or refactoring logs, instrumenting request paths, defining event schemas, reducing log cost/cardinality, enforcing redaction/PII policy, correlating logs with traces, or reviewing Go services for observability gaps.
gleam-otp-actors
| name | go-testing |
| description | Go Testing Skill |
Version: 1.0 Purpose: Test-Driven Development for Go/Bubbletea
TDD with Go uses the built-in testing package. This skill covers patterns for testing Bubbletea models, services, and concurrent code.
Core Principle: Tests are specifications, not just coverage metrics.
func TestTaskCardTitle(t *testing.T) {
card := TaskCard{Title: "Test Task"}
want := "Test Task"
got := card.GetTitle()
if got != want {
t.Errorf("GetTitle() = %q, want %q", got, want)
}
}
// Run: go test
// Expected: FAIL (red) - no implementation exists yet
CRITICAL: Write ONLY enough code to make test pass. Don't over-engineer.
type TaskCard struct {
Title string
}
func (c TaskCard) GetTitle() string {
return c.Title
}
// Run: go test
// Expected: PASS (green)
Only refactor AFTER tests pass:
// Extract common method if needed
func (c TaskCard) String() string {
return fmt.Sprintf("Task: %s", c.Title)
}
// Run: go test
// Expected: Still PASS (green)
func TestBoardModelInit(t *testing.T) {
m := NewBoardModel()
cmd := m.Init()
if cmd != nil {
t.Errorf("Init() should return nil, got %v", cmd)
}
}
func TestBoardModelUpdate_KeyPress(t *testing.T) {
m := NewBoardModel()
msg := tea.KeyMsg{Type: tea.KeyDown}
newModel, cmd := m.Update(msg)
updated := newModel.(BoardModel)
if updated.cursor != 1 {
t.Errorf("cursor = %d, want 1", updated.cursor)
}
if cmd != nil {
t.Errorf("cmd should be nil")
}
}
func TestBoardModel_EnterTask(t *testing.T) {
m := NewBoardModel()
m.tasks = []Task{{ID: "az-1", Title: "Test"}}
msg := tea.KeyMsg{Type: tea.KeyEnter}
newModel, _ := m.Update(msg)
updated := newModel.(BoardModel)
if updated.state != StateDetail {
t.Errorf("state = %v, want StateDetail", updated.state)
}
}
func TestBoardModelView(t *testing.T) {
m := NewBoardModel()
m.tasks = []Task{{ID: "az-1", Title: "Test Task"}}
view := m.View()
if !strings.Contains(view, "Test Task") {
t.Errorf("View() should contain task title")
}
}
// Define interface
type CommandRunner interface {
Run(ctx context.Context, name string, args ...string) ([]byte, error)
}
// Mock implementation
type mockRunner struct {
output []byte
err error
}
func (m *mockRunner) Run(ctx context.Context, name string, args ...string) ([]byte, error) {
return m.output, m.err
}
// Test using mock
func TestBeadsClientList(t *testing.T) {
runner := &mockRunner{output: []byte(`[{"id":"az-1","title":"Test"}]`)}
client := NewClient(runner, slog.Default())
tasks, err := client.List(context.Background())
if err != nil {
t.Fatalf("List() error = %v", err)
}
if len(tasks) != 1 {
t.Errorf("len(tasks) = %d, want 1", len(tasks))
}
}
func TestBeadsClientList_Error(t *testing.T) {
runner := &mockRunner{err: errors.New("command failed")}
client := NewClient(runner, slog.Default())
_, err := client.List(context.Background())
if err == nil {
t.Error("expected error, got nil")
}
}
go test -race ./...
func TestServiceWithContext(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
svc := NewService()
result, err := svc.DoWork(ctx)
if err != nil {
t.Errorf("DoWork() error = %v", err)
}
if result != "expected" {
t.Errorf("result = %v, want expected", result)
}
}
func TestWorkerPool(t *testing.T) {
jobs := make(chan int, 3)
results := make(chan int, 3)
go worker(jobs, results)
jobs <- 1
jobs <- 2
close(jobs)
got := []int{<-results, <-results}
want := []int{1, 2}
if !reflect.DeepEqual(got, want) {
t.Errorf("results = %v, want %v", got, want)
}
}
When a test or package appears to stall, do not stop at wall-clock timing. Timeouts and stack traces are usually more useful than elapsed durations alone.
Recommended workflow:
go test ./internal/daemon -run '^TestName$' -count=1 -timeout 10s.stopped row can legitimately force stop-enforcement logic instead of recovery logic and create misleading hangs in fake tmux runners.NEVER trust AI-generated tests uncritically.
After AI generates tests or implementation code:
❌ Write tests AFTER implementation:
// BAD: Implementation exists, test written to pass
func CalculateDiscount(price float64) float64 {
return price * 0.9
}
// Test written to match implementation (wrong order!)
func TestDiscount(t *testing.T) {
got := CalculateDiscount(100)
if got != 90 {
t.Errorf("wrong") // Locks in bug
}
}
✅ CORRECT: Write test FIRST as spec:
// GOOD: Test specifies behavior first
func TestCalculateDiscount_AppliesTenPercent(t *testing.T) {
got := CalculateDiscount(100)
want := 90.0
if got != want {
t.Errorf("CalculateDiscount(100) = %v, want %v", got, want)
}
}
// Implementation written to satisfy spec
func CalculateDiscount(price float64) float64 {
return price * 0.9
}
// ❌ WRONG: Delete test to "fix" build
func TestEdgeCase(t *testing.T) {
got := handleEdgeCase()
if got != "expected" {
t.Errorf("wrong")
}
}
// ✅ CORRECT: Fix implementation to satisfy test
func handleEdgeCase() string {
return "expected" // Actually implement the logic
}
func TestCalculateDiscount(t *testing.T) {
tests := []struct {
name string
price float64
want float64
}{
{"normal price", 100, 90},
{"zero price", 0, 0},
{"large price", 1000000, 900000},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := CalculateDiscount(tt.price)
if got != tt.want {
t.Errorf("CalculateDiscount(%v) = %v, want %v",
tt.price, got, tt.want)
}
})
}
}
// ❌ BAD: Unhelpful
if got != want {
t.Error("wrong")
}
// ✅ GOOD: Clear and informative
if got != want {
t.Errorf("CreateWorktree(%q) = %v, want %v", input, got, want)
}
func TestBoardModel(t *testing.T) {
// Helper for creating test model
newTestModel := func(t *testing.T) BoardModel {
t.Helper()
m := NewBoardModel()
m.tasks = []Task{{ID: "az-1", Title: "Test"}}
return m
}
t.Run("displays tasks", func(t *testing.T) {
m := newTestModel(t)
view := m.View()
if !strings.Contains(view, "Test") {
t.Error("view should contain task title")
}
})
}
# Run all tests
go test ./...
# Run specific package
go test ./internal/app
# Run with race detector
go test -race ./...
# Run with coverage
go test -cover ./...
# Verbose output
go test -v ./...
# Run specific test
go test -run TestBoardModel ./internal/app
# Run subtests
go test -run TestBoardModel/displays_tasks ./internal/app
# Coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
Before accepting AI-generated tests or implementation:
go test -race)If ANY fail: Ask AI to fix before proceeding.