【问题标题】:Set particular environment variables during execution of a test suite在执行测试套件期间设置特定的环境变量
【发布时间】:2021-10-11 14:37:18
【问题描述】:

我想在 Go 中运行与环境变量有关的单元测试 fxn。

在某个时候我会去(没有双关语)

    for test := range tests {
        for k, v := range test.envVars {
            os.Setenv(k, v)
        }

有没有办法确保在测试执行期间,通过上述对os.Setenv() 的调用设置的变量将是唯一可用于测试函数的环境变量

【问题讨论】:

  • 更好的方法是让被测代码不直接读取环境本身。

标签: go testing environment-variables


【解决方案1】:

您可以使用os.Environ获取当前环境,使用os.Unsetenv取消设置。

您可能还需要在测试完成后恢复这些变量,为此您可以在每个环境中使用subtest(*testing.T).Cleanup (https://play.golang.org/p/A5HGZwWm-NS):

    for _, tc := range tests {
        t.Run(tc.name, func(t *testing.T) {
            // NOTE: do NOT call t.Parallel in this subtest or its parent,
            // or the environment WILL be corrupted.
            //
            // (However, *subtests of* t may be run in parallel.)

            prevEnv := os.Environ()
            for _, entry := range prevEnv {
                parts := strings.SplitN(entry, "=", 2)
                os.Unsetenv(parts[0])
            }
            for k, v := range tc.envVars {
                os.Setenv(k, v)
            }
            t.Cleanup(func() {
                for k := range tc.envVars {
                    os.Unsetenv(k)
                }
                for _, entry := range prevEnv {
                    parts := strings.SplitN(entry, "=", 2)
                    os.Setenv(parts[0], parts[1])
                }
            })

            …
        })
    }

还要注意,Go 1.17 添加了(*testing.T).Setenv 方法,它会自动清理修改。不过目前还没有对应的(*testing.T).Unsetenv


如果您希望能够并行运行测试,您可以改为使用带有os/exec-test.run 标志的子测试来重新执行特定的子测试作为主测试进程的子进程,并具有自己独特的环境。

【讨论】:

  • 但是,我想带回(设置)环境不是强制性的(因为只有运行测试的特定操作系统系统进程才会受到此操作的影响(只要我同意)
  • 这是正确的——尽管如果您希望它应用于整个过程中的所有测试,未来的维护者(包括您自己!)可能更清楚地取消设置 TestMain 中的变量而不是一个单独的测试函数。
猜你喜欢
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-20
  • 2012-10-17
  • 2023-03-29
  • 2016-08-11
相关资源
最近更新 更多