本文介绍一种可复现、可断言的测试方法,用于在 go 单元测试中精确限制并验证 goroutine 的并发执行数量,避免竞态与资源超限,适用于限流、工作池等场景。
在 Go 单元测试中直接“计数”正在运行的 goroutine 数量(如通过 runtime.NumGo

核心思路是:
以下是一个可直接用于 *_test.go 的完整测试示例:
func TestGoroutineConcurrencyLimit(t *testing.T) {
const (
count = 10
limit = 3
)
var (
wg sync.WaitGroup
concurrentCnt int
mu sync.Mutex
failed bool
)
wg.Add(count)
// Mock worker: 模拟实际业务逻辑,但加入并发安全的计数与断言
mockWorker := func() {
defer func() {
mu.Lock()
concurrentCnt--
mu.Unlock()
wg.Done()
}()
mu.Lock()
concurrentCnt++
if concurrentCnt > limit {
failed = true // 立即捕获超限,无需等待全部结束
}
mu.Unlock()
time.Sleep(50 * time.Millisecond) // 模拟耗时操作
}
// spawn 函数:确保最多 limit 个 goroutine 并发执行
spawn := func(fn func(), total, maxConcurrent int) {
limiter := make(chan struct{}, maxConcurrent)
for i := 0; i < total; i++ {
limiter <- struct{}{} // 获取令牌
go func() {
defer func() { <-limiter }() // 归还令牌
fn()
}()
}
}
spawn(mockWorker, count, limit)
wg.Wait()
if failed {
t.Fatalf("concurrency limit %d violated: observed >%d goroutines running simultaneously", limit, limit)
}
t.Logf("✅ Passed: exactly %d goroutines ran concurrently (limit=%d)", limit, limit)
}⚠️ 注意事项:
通过这种结构化、可观测、可断言的方式,你不仅能验证“是否启动了指定数量的 goroutine”,更能精准保障“任何时候都未超过预期并发上限”,真正实现对并发行为的确定性测试。