en un clic
testing-patterns
Table-driven tests, -race flag, stub patterns
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Menu
Table-driven tests, -race flag, stub patterns
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Basé sur la classification professionnelle SOC
How to write comprehensive architectural proposals that drive alignment before code is written
How the eval engine works: generate → grade → review → report
Record final outcomes to history.md, not intermediate requests or reversed decisions
Tone enforcement patterns for external-facing community responses
Team initialization flow (Phase 1 proposal + Phase 2 creation)
Core conventions and patterns for this codebase
| name | testing-patterns |
| description | Table-driven tests, -race flag, stub patterns |
| domain | quality |
| confidence | high |
| source | hyoka/internal/*_test.go files |
Hyoka test suite follows Go idioms: table-driven tests for comprehensive coverage, -race flag for detecting concurrency issues, and stub patterns for mocking external dependencies (Copilot SDK, file system).
Use table-driven tests to test multiple scenarios with the same logic:
✓ Correct:
func TestBehaviorGrader_ConstraintValidation(t *testing.T) {
tests := []struct {
name string
config map[string]any
actionLog []ActionEvent
expect bool
wantErr string
}{
{
name: "required tools present",
config: map[string]any{
"required_tools": []any{"read_file", "edit_file"},
},
actionLog: []ActionEvent{
{Tool: "read_file", TurnNumber: 1},
{Tool: "edit_file", TurnNumber: 2},
},
expect: true,
},
{
name: "required tool missing",
config: map[string]any{
"required_tools": []any{"read_file"},
},
actionLog: []ActionEvent{
{Tool: "bash", TurnNumber: 1},
},
expect: false,
wantErr: "required tool not found",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g, _ := NewBehaviorGrader("test", tt.config)
result, err := g.Grade(context.Background(), GraderInput{
ActionLog: tt.actionLog,
})
if (err != nil) != (tt.wantErr != "") {
t.Fatalf("unexpected error: %v", err)
}
if result.Pass != tt.expect {
t.Errorf("expected Pass=%v, got %v", tt.expect, result.Pass)
}
})
}
}
Always run tests with -race flag:
go test -race ./hyoka/...
The -race detector catches unsynchronized access to shared memory in concurrent code. This is critical for:
When testing engine behavior without real graders:
type StubGrader struct {
gradeFn func(context.Context, GraderInput) (GraderResult, error)
}
func (sg *StubGrader) Grade(ctx context.Context, input GraderInput) (GraderResult, error) {
return sg.gradeFn(ctx, input)
}
// Usage in test
stubGrader := &StubGrader{
gradeFn: func(_ context.Context, _ GraderInput) (GraderResult, error) {
return GraderResult{Pass: true, Score: 1.0}, nil
},
}
Mock file operations without touching disk:
type stubFileReader struct {
readFn func(path string) (string, error)
}
func (s *stubFileReader) Read(path string) (string, error) {
return s.readFn(path)
}
// Usage
stubFS := &stubFileReader{
readFn: func(path string) (string, error) {
if path == "/test/main.py" {
return "# Generated code", nil
}
return "", os.ErrNotExist
},
}
*_test.go in same package)*_integration_test.go)testdata/ directory for test files# All tests
go test ./hyoka/...
# With race detector
go test -race ./hyoka/...
# Specific test
go test -run TestBehaviorGrader ./hyoka/internal/graders
# Verbose with coverage
go test -v -cover ./hyoka/...
-race failures (concurrency bugs are subtle)hyoka/internal/graders/*_test.gohyoka/internal/eval/*_test.gohyoka/testdata/