GitHub user Tsukikage7 created a discussion: [Best Practice] 避免单元测试中的全局状态竞争问题
### 背景
在 #848 PR review 过程中,发现了一个潜在的测试稳定性问题,值得在项目中推广避免。
### 问题描述
当测试修改全局变量时,如果使用 `go test -parallel` 或测试框架并行执行,可能导致 **flaky
test**(不稳定测试)。
**问题代码示例:**
```go
var GlobalConfig = NewDefaultConfig() // 全局变量
func TestSomething(t *testing.T) {
original := GlobalConfig
GlobalConfig = &Config{...} // 修改全局状态
// 测试逻辑...
GlobalConfig = original // 恢复 - 如果测试 panic,这行不会执行!
}
风险:
1. 并行测试时产生竞态条件
2. 测试失败/panic 时无法恢复全局状态,影响后续测试
推荐做法
1. 使用 defer 确保恢复:
func TestSomething(t *testing.T) {
original := GlobalConfig
defer func() { GlobalConfig = original }() // 始终恢复
GlobalConfig = &Config{...}
// 测试逻辑...
}
2. 使用依赖注入替代全局变量:
// 不推荐
func DoSomething() {
config := GlobalConfig // 依赖全局变量
}
// 推荐
func DoSomething(config *Config) {
// 使用传入的配置
}
3. 添加注释说明:
func TestModifyGlobalState(t *testing.T) {
// Note: This test modifies global state, cannot run in parallel
// ...
}
检测方法
使用 -race 标志运行测试可以检测竞态条件:
go test ./... -race
相关 PR
- #848 - 修复了 TestSetControllerConfig 中的全局状态恢复问题
---
GitHub link: https://github.com/apache/dubbo-go-pixiu/discussions/851
----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]