Skills Plugins MCP Prompt Model 博客 我的中心

golang-testing

Go测试模式包括表格驱动测试、子测试、基准测试、模糊测试和测试覆盖率。遵循TDD方法论,采用地道的Go实践。

DeepseekModel Curated skill Quality Excellent · 90 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-docs-zh-cn-skills-golang-testing-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name golang-testing description Go测试模式包括表格驱动测试、子测试、基准测试、模糊测试和测试覆盖率。遵循TDD方法论,采用地道的Go实践。 origin ECC Go 测试模式 遵循 TDD 方法论,用于编写可靠、可维护测试的全面 Go 测试模式。 何时激活 编写新的 Go 函数或方法时 为现有代码添加测试覆盖率时 为性能关键代码创建基准测试时 为输入验证实现模糊测试时 在 Go 项目中遵循 TDD 工作流时 Go 的 TDD 工作流 红-绿-重构循环 RED → 首先编写一个失败的测试 GREEN → 编写最少的代码来通过测试 REFACTOR → 改进代码,同时保持测试通过 REPEAT → 继续处理下一个需求 Go 中的分步 TDD // Step 1: Define the interface/signature // calculator.go package calculator func Add (a, b int ) int { panic ( "not implemented" ) // Placeholder } // Step 2: Write failing test (RED) // calculator_test.go package calculator import "testing" func TestAdd (t *testing.T) { got := Add( 2 , 3 ) want := 5 if got != want { t.Errorf( "Add(2, 3) = %d; want %d" , got, want) } } // Step 3: Run test - verify FAIL // $ go test // --- FAIL: TestAdd (0.00s) // panic: not implemented // Step 4: Implement minimal code (GREEN) func Add (a, b int ) int { return a + b } // Step 5: Run test - verify PASS // $ go test // PASS // Step 6: Refactor if needed, verify tests still pass 表驱动测试 Go 测试的标准模式。以最少的代码实现全面的覆盖。 func TestAdd (t *testing.T) { tests := [] struct { name string a, b int expected int }{ { "positive numbers" , 2 , 3 , 5 }, { "negative numbers" , -1 , -2 , -3 }, { "zero values" , 0 , 0 , 0 }, { "mixed signs" , -1 , 1 , 0 }, { "large numbers" , 1000000 , 2000000 , 3000000 }, } for _, tt := range tests { t.Run(tt.name, func (t *testing.T) { got := Add(tt.a, tt.b) if got != tt.expected { t.Errorf( "Add(%d, %d) = %d; want %d" , tt.a, tt.b, got, tt.expected) } }) } } 包含错误情况的表驱动测试 func TestParseConfig (t *testing.T) { tests := [] struct { name string input string want *Config wantErr bool }{ { name: "valid config" , input: `{"host": "localhost", "port": 8080}` , want: &Config{Host: "localhost" , Port: 8080 }, }, { name: "invalid JSON" , input: `{invalid}` , wantErr: true , }, { name: "empty input" , input: "" , wantErr: true , }, { name: "minimal config" , input: `{}` , want: &Config{}, // Zero value config }, } for _, tt := range tests { t.Run(tt.name, func (t *testing.T) { got, err := ParseConfig(tt.input) if tt.wantErr { if err == nil { t.Error( "expected error, got nil" ) } return } if err != nil { t.Fatalf( "unexpected error: %v" , err) } if !reflect.DeepEqual(got, tt.want) { t.Errorf( "got %+v; want %+v" , got, tt.want) } }) } } 子测试和子基准测试 组织相关测试 func TestUser (t *testing.T) { // Setup shared by all subtests db := setupTestDB(t) t.Run( "Create" , func (t *testing.T) { user := &User{Name: "Alice" } err := db.CreateUser(user) if err != nil { t.Fatalf( "CreateUser failed: %v" , err) } if user.ID == "" { t.Error( "expected user ID to be set" ) } }) t.Run( "Get" , func (t *testing.T) { user, err := db.GetUser( "alice-id" ) if err != nil { t.Fatalf( "GetUser failed: %v" , err) } if user.Name != "Alice" { t.Errorf( "got name %q; want %q" , user.Name, "Alice" ) } }) t.Run( "Update" , func (t *testing.T) { // ... }) t.Run( "Delete" , func (t *testing.T) { // ... }) } 并行子测试 func TestParallel (t *testing.T) { tests := [] struct { name string input string }{ { "case1" , "input1" }, { "case2" , "input2" }, { "case3" , "input3" }, } for _, tt := range tests { tt := tt // Capture range variable t.Run(tt.name, func (t *testing.T) { t.Parallel() // Run subtests in parallel result := Process(tt.input) // assertions... _ = result }) } } 测试辅助函数 辅助函数 func setupTestDB (t *testing.T) *sql.DB { t.Helper() // Marks this as a helper function db, err := sql.Open( "sqlite3" , ":memory:" ) if err != nil { t.Fatalf( "failed to open database: %v" , err) } // Cleanup when test finishes t.Cleanup( func () { db.Close() }) // Run migrations if _, err := db.Exec(schema); err != nil { t.Fatalf( "failed to create schema: %v" , err) } return db } func assertNoError (t *testing.T, err error ) { t.Helper() if err != nil { t.Fatalf( "unexpected error: %v" , err) } } func assertEqual [ T comparable ] (t *testing.T, got, want T) { t.Helper() if got != want { t.Errorf( "got %v; want %v" , got, want) } } 临时文件和目录 func TestFileProcessing (t *testing.T) { // Create temp directory - automatically cleaned up tmpDir := t.TempDir() // Create test file testFile := filepath.Join(tmpDir, "test.txt" ) err := os.WriteFile(testFile, [] byte ( "test content" ), 0644 ) if err != nil { t.Fatalf( "failed to create test file: %v" , err) } // Run test result, err := ProcessFile(testFile) if err != nil { t.Fatalf( "ProcessFile failed: %v" , err) } // Assert... _ = result } 黄金文件 针对存储在 testdata/ 中的预期输出文件进行测试。 var update = flag.Bool( "update" , false , "update golden files" ) func TestRender (t *testing.T) { tests := [] struct { name string input Template }{ { "simple" , Template{Name: "test" }}, { "complex" , Template{Name: "test" , Items: [] string { "a" , "b" }}}, } for _, tt := range tests { t.Run(tt.name, func (t *testing.T) { got := Render(tt.input) golden := filepath.Join( "testdata" , tt.name+ ".golden" ) if *update { // Update golden file: go test -update err := os.WriteFile(golden, got, 0644 ) if err != nil { t.Fatalf( "failed to update golden file: %v" , err) } } want, err := os.ReadFile(golden) if err != nil { t.Fatalf( "failed to read golden file: %v" , err) } if !bytes.Equal(got, want) { t.Errorf( "output mismatch:\ngot:\n%s\nwant:\n%s" , got, want) } }) } } 使用接口进行模拟 基于接口的模拟 // Define interface for dependencies type UserRepository interface { GetUser(id string ) (*User, error ) SaveUser(user *User) error } // Production implementation type PostgresUserRepository struct { db *sql.DB } func (r *PostgresUserRepository) GetUser(id string ) (*User, error ) { // Real database query } // Mock implementation for tests type MockUserRepository struct { GetUserFunc func (id string ) (*User, error ) SaveUserFunc func (user *User) error } func (m *MockUserRepository) GetUser(id string ) (*User, error ) { return m.GetUserFunc(id) } func (m *MockUserRepository) SaveUser(user *User) error { return m.SaveUserFunc(user) } // Test using mock func TestUserService (t *testing.T) { mock := &MockUserRepository{ GetUserFunc: func (id string ) (*User, error ) { if id == "123" { return &User{ID: "123" , Name: "Alice" }, nil } return nil , ErrNotFound }, } service := NewUserService(mock) user, err := service.GetUserProfile( "123" ) if err != nil { t.Fatalf( "unexpected error: %v" , err) } if user.Name != "Alice" { t.Errorf( "got name %q; want %q" , user.Name, "Alice" ) } } 基准测试 基本基准测试 func BenchmarkProcess (b *testing.B) { data := generateTestData( 1000 ) b.ResetTimer() // Don't count setup time for i := 0 ; i < b.N; i++ { Process(data) } } // Run: go test -bench=BenchmarkProcess -benchmem // Output: BenchmarkProcess-8 10000 105234 ns/op 4096 B/op 10 allocs/op 不同大小的基准测试 func BenchmarkSort (b *testing.B) { sizes := [] int { 100 , 1000 , 10000 , 100000 } for _, size := range sizes { b.Run(fmt.Sprintf( "size=%d" , size), func (b *testing.B) { data := generateRandomSlice(size) b.ResetTimer() for i := 0 ; i < b.N; i++ { // Make a copy to avoid sorting already sorted data tmp := make ([] int , len (data)) copy (tmp, data) sort.Ints(tmp) } }) } } 内存分配基准测试 func BenchmarkStringConcat (b *testing.B) { parts := [] string { "hello" , "world" , "foo" , "bar" , "baz" } b.Run( "plus" , func (b *testing.B) { for i := 0 ; i < b.N; i++ { var s string for _, p := range parts { s += p } _ = s } }) b.Run( "builder" , func (b *testing.B) { for i := 0 ; i < b.N; i++ { var sb strings.Builder for _, p := range parts { sb.WriteString(p) } _ = sb.String() } }) b.Run( "join" , func (b *testing.B) { for i := 0 ; i < b.N; i++ { _ = strings.Join(parts, "" ) } }) } 模糊测试 (Go 1.18+) 基本模糊测试 func FuzzParseJSON (f *testing.F) { // Add seed corpus f.Add( `{"name": "test"}` ) f.Add( `{"count": 123}` )
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。