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]

Reply via email to