Loading...
Loading...
Compare original and translation side by side
ultrathinkgotestst.Parallel()Community default. A company skill that explicitly supersedesskill takes precedence.samber/cc-skills-golang@golang-testing
ultrathinkgotestst.Parallel()社区默认规则:如果公司内部有明确替代的技能,则以该技能为准。samber/cc-skills-golang@golang-testing
namet.Run//go:build integrationt.Parallel()goleak.VerifyTestMainTestMainnamet.Run//go:build integrationt.Parallel()TestMaingoleak.VerifyTestMain// package_test.go - tests in same package (white-box, access unexported)
package mypackage
// mypackage_test.go - tests in test package (black-box, public API only)
package mypackage_test// package_test.go - 与源码同包的测试(白盒测试,可访问未导出成员)
package mypackage
// mypackage_test.go - 独立测试包的测试(黑盒测试,仅测试公开API)
package mypackage_testfunc TestAdd(t *testing.T) { ... } // function test
func TestMyStruct_MyMethod(t *testing.T) { ... } // method test
func BenchmarkAdd(b *testing.B) { ... } // benchmark
func ExampleAdd() { ... } // examplefunc TestAdd(t *testing.T) { ... } // 函数测试
func TestMyStruct_MyMethod(t *testing.T) { ... } // 方法测试
func BenchmarkAdd(b *testing.B) { ... } // 基准测试
func ExampleAdd() { ... } // 示例代码func TestCalculatePrice(t *testing.T) {
tests := []struct {
name string
quantity int
unitPrice float64
expected float64
}{
{
name: "single item",
quantity: 1,
unitPrice: 10.0,
expected: 10.0,
},
{
name: "bulk discount - 100 items",
quantity: 100,
unitPrice: 10.0,
expected: 900.0, // 10% discount
},
{
name: "zero quantity",
quantity: 0,
unitPrice: 10.0,
expected: 0.0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := CalculatePrice(tt.quantity, tt.unitPrice)
if got != tt.expected {
t.Errorf("CalculatePrice(%d, %.2f) = %.2f, want %.2f",
tt.quantity, tt.unitPrice, got, tt.expected)
}
})
}
}func TestCalculatePrice(t *testing.T) {
tests := []struct {
name string
quantity int
unitPrice float64
expected float64
}{
{
name: "single item",
quantity: 1,
unitPrice: 10.0,
expected: 10.0,
},
{
name: "bulk discount - 100 items",
quantity: 100,
unitPrice: 10.0,
expected: 900.0, // 10% discount
},
{
name: "zero quantity",
quantity: 0,
unitPrice: 10.0,
expected: 0.0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := CalculatePrice(tt.quantity, tt.unitPrice)
if got != tt.expected {
t.Errorf("CalculatePrice(%d, %.2f) = %.2f, want %.2f",
tt.quantity, tt.unitPrice, got, tt.expected)
}
})
}
}httptesthttptestgo.uber.org/goleakimport (
"testing"
"go.uber.org/goleak"
)
func TestMain(m *testing.M) {
goleak.VerifyTestMain(m)
}func TestMain(m *testing.M) {
goleak.VerifyTestMain(m,
goleak.IgnoreCurrent(),
)
}func TestWorkerPool(t *testing.T) {
defer goleak.VerifyNone(t)
// ... test code ...
}go.uber.org/goleakimport (
"testing"
"go.uber.org/goleak"
)
func TestMain(m *testing.M) {
goleak.VerifyTestMain(m)
}func TestMain(m *testing.M) {
goleak.VerifyTestMain(m,
goleak.IgnoreCurrent(),
)
}func TestWorkerPool(t *testing.T) {
defer goleak.VerifyNone(t)
// ... 测试代码 ...
}Experimental:is not yet covered by Go's compatibility guarantee. Its API may change in future releases. For stable alternatives, usetesting/synctest(see Mocking).clockwork
testing/synctestsynctestimport (
"testing"
"time"
"testing/synctest"
"github.com/stretchr/testify/assert"
)
func TestChannelTimeout(t *testing.T) {
synctest.Run(func(t *testing.T) {
is := assert.New(t)
ch := make(chan int, 1)
go func() {
time.Sleep(50 * time.Millisecond)
ch <- 42
}()
select {
case v := <-ch:
is.Equal(42, v)
case <-time.After(100 * time.Millisecond):
t.Fatal("timeout occurred")
}
})
}synctesttime.Sleeptime.After实验性功能:尚未纳入Go的兼容性保障范围,其API可能在未来版本中变更。如需稳定替代方案,请使用testing/synctest(参考Mocking)。clockwork
testing/synctestsynctestimport (
"testing"
"time"
"testing/synctest"
"github.com/stretchr/testify/assert"
)
func TestChannelTimeout(t *testing.T) {
synctest.Run(func(t *testing.T) {
is := assert.New(t)
ch := make(chan int, 1)
go func() {
time.Sleep(50 * time.Millisecond)
ch <- 42
}()
select {
case v := <-ch:
is.Equal(42, v)
case <-time.After(100 * time.Millisecond):
t.Fatal("timeout occurred")
}
})
}synctesttime.Sleeptime.Aftersamber/cc-skills-golang@golang-benchmarkb.Loop()benchstatfunc BenchmarkStringConcatenation(b *testing.B) {
b.Run("plus-operator", func(b *testing.B) {
for i := 0; i < b.N; i++ {
result := "a" + "b" + "c"
_ = result
}
})
b.Run("strings.Builder", func(b *testing.B) {
for i := 0; i < b.N; i++ {
var builder strings.Builder
builder.WriteString("a")
builder.WriteString("b")
builder.WriteString("c")
_ = builder.String()
}
})
}func BenchmarkFibonacci(b *testing.B) {
sizes := []int{10, 20, 30}
for _, size := range sizes {
b.Run(fmt.Sprintf("n=%d", size), func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
Fibonacci(size)
}
})
}
}samber/cc-skills-golang@golang-benchmarkb.Loop()benchstatfunc BenchmarkStringConcatenation(b *testing.B) {
b.Run("plus-operator", func(b *testing.B) {
for i := 0; i < b.N; i++ {
result := "a" + "b" + "c"
_ = result
}
})
b.Run("strings.Builder", func(b *testing.B) {
for i := 0; i < b.N; i++ {
var builder strings.Builder
builder.WriteString("a")
builder.WriteString("b")
builder.WriteString("c")
_ = builder.String()
}
})
}func BenchmarkFibonacci(b *testing.B) {
sizes := []int{10, 20, 30}
for _, size := range sizes {
b.Run(fmt.Sprintf("n=%d", size), func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
Fibonacci(size)
}
})
}
}t.Parallel()func TestParallelOperations(t *testing.T) {
tests := []struct {
name string
data []byte
}{
{"small data", make([]byte, 1024)},
{"medium data", make([]byte, 1024*1024)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
is := assert.New(t)
result := Process(tt.data)
is.NotNil(result)
})
}
}t.Parallel()func TestParallelOperations(t *testing.T) {
tests := []struct {
name string
data []byte
}{
{"small data", make([]byte, 1024)},
{"medium data", make([]byte, 1024*1024)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
is := assert.New(t)
result := Process(tt.data)
is.NotNil(result)
})
}
}func FuzzReverse(f *testing.F) {
f.Add("hello")
f.Add("")
f.Add("a")
f.Fuzz(func(t *testing.T, input string) {
reversed := Reverse(input)
doubleReversed := Reverse(reversed)
if input != doubleReversed {
t.Errorf("Reverse(Reverse(%q)) = %q, want %q", input, doubleReversed, input)
}
})
}func FuzzReverse(f *testing.F) {
f.Add("hello")
f.Add("")
f.Add("a")
f.Fuzz(func(t *testing.T, input string) {
reversed := Reverse(input)
doubleReversed := Reverse(reversed)
if input != doubleReversed {
t.Errorf("Reverse(Reverse(%q)) = %q, want %q", input, doubleReversed, input)
}
})
}go testfunc ExampleCalculatePrice() {
price := CalculatePrice(100, 10.0)
fmt.Printf("Price: %.2f\n", price)
// Output: Price: 900.00
}
func ExampleCalculatePrice_singleItem() {
price := CalculatePrice(1, 25.50)
fmt.Printf("Price: %.2f\n", price)
// Output: Price: 25.50
}go testfunc ExampleCalculatePrice() {
price := CalculatePrice(100, 10.0)
fmt.Printf("Price: %.2f\n", price)
// Output: Price: 900.00
}
func ExampleCalculatePrice_singleItem() {
price := CalculatePrice(1, 25.50)
fmt.Printf("Price: %.2f\n", price)
// Output: Price: 25.50
}undefinedundefinedundefinedundefined//go:build integration
package mypackage
func TestDatabaseIntegration(t *testing.T) {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
t.Fatal(err)
}
defer db.Close()
// Test real database operations
}go test -tags=integration ./...//go:build integration
package mypackage
func TestDatabaseIntegration(t *testing.T) {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
t.Fatal(err)
}
defer db.Close()
// 测试真实数据库操作
}go test -tags=integration ./...thelperparalleltesttestifylintsamber/cc-skills-golang@golang-linterthelperparalleltesttestifylintsamber/cc-skills-golang@golang-lintersamber/cc-skills-golang@golang-stretchr-testifysamber/cc-skills-golang@golang-databasesamber/cc-skills-golang@golang-concurrencysamber/cc-skills-golang@golang-continuous-integrationsamber/cc-skills-golang@golang-lintersamber/cc-skills-golang@golang-stretchr-testifysamber/cc-skills-golang@golang-databasesamber/cc-skills-golang@golang-concurrencysamber/cc-skills-golang@golang-continuous-integrationsamber/cc-skills-golang@golang-lintergo test ./... # all tests
go test -run TestName ./... # specific test by exact name
go test -run TestName/subtest ./... # subtests within a test
go test -run 'Test(Add|Sub)' ./... # multiple tests (regexp OR)
go test -run 'Test[A-Z]' ./... # tests starting with capital letter
go test -run 'TestUser.*' ./... # tests matching prefix
go test -run '.*Validation.*' ./... # tests containing substring
go test -run TestName/. ./... # all subtests of TestName
go test -run '/(unit|integration)' ./... # filter by subtest name
go test -race ./... # race detection
go test -cover ./... # coverage summary
go test -bench=. -benchmem ./... # benchmarks
go test -fuzz=FuzzName ./... # fuzzing
go test -tags=integration ./... # integration testsgo test ./... # 运行所有测试
go test -run TestName ./... # 运行指定名称的测试
go test -run TestName/subtest ./... # 运行指定测试下的子测试
go test -run 'Test(Add|Sub)' ./... # 运行多个测试(正则或匹配)
go test -run 'Test[A-Z]' ./... # 运行以大写字母开头的测试
go test -run 'TestUser.*' ./... # 运行匹配前缀的测试
go test -run '.*Validation.*' ./... # 运行包含指定子串的测试
go test -run TestName/. ./... # 运行指定测试的所有子测试
go test -run '/(unit|integration)' ./... # 按子测试名称过滤
go test -race ./... # 启用竞态检测运行测试
go test -cover ./... # 查看覆盖率摘要
go test -bench=. -benchmem ./... # 运行基准测试
go test -fuzz=FuzzName ./... # 运行模糊测试
go test -tags=integration ./... # 运行集成测试