nosetests 框架:如何将环境变量传递给我的测试?

nosetests framework: how to pass environment variables to my tests?

我有一个测试套件作为更大构建框架的一部分执行,用 Python 编写。有些测试需要参数,我想使用环境变量传递这些参数。

显然 nosetests runner 有一个 env 参数,它可以满足我的要求,according to the documentation. 然而,它似乎并没有像预期的那样工作?

这里有一个最小的测试脚本来举例说明问题:

#!/usr/bin/env python
# pip install nose

import os, nose, unittest

class Test(unittest.TestCase):
    def test_env(self):
        self.assertEquals(os.environ.get('HELLO'), 'WORLD')

if __name__ == '__main__':
    nose.run(env={'HELLO': 'WORLD'})

断言失败,因为 env 参数没有传递给测试。有谁知道为什么?

注意:我通过启动控制台 nosetests 工具解决了这个问题:

#!/usr/bin/env python

import sys, os, nose, unittest, subprocess

class Test(unittest.TestCase):
    def test_env(self):
        self.assertEquals(os.environ.get('HELLO'), 'WORLD')

if __name__ == '__main__':
    subprocess.Popen(['nosetests', sys.argv[0]],
                     env={'HELLO': 'WORLD'}).wait()

然而,这感觉像是一个拼凑,我仍然有兴趣学习如何正确使用 nose.run()

我也无法让 env 自行运行,但我想出了一个解决方案,我认为它比打开一个子进程稍微不那么笨拙。您可以在调用 nose.run() 之前修改 os.environ 变量,只要测试在同一进程中 运行,测试都会看到修改后的 os.environ

#!/usr/bin/env python
import os, nose, unittest

class Test(unittest.TestCase):
    def test_env(self):
        self.assertEquals(os.environ.get('HELLO'), 'WORLD')

if __name__ == '__main__':
    os.environ["HELLO"] = "WORLD"
    nose.run()

我查看了 nose 来源(core.py 和 config.py)并追踪了 env 参数的处理。我认为 env 参数并不像您想象的那样。它不是用于设置或添加到受测者的环境中。它仅适用于特定于鼻子的配置选项。 然而,如果能有您(和我)正在寻找的功能就好了。

我遇到过在测试过程中需要环境变量的相同类型的情况。

我使用 bash 脚本首先设置环境变量,运行 测试,然后 unset 环境变量。

run_tests.sh中:

#!/bin/bash
export HELLO='WORLD'
nosetests -v
unset HELLO

然后在 tests/test_env.py:

#!/usr/bin/env python
import os, unittest

class Test(unittest.TestCase):
    def test_env(self):
        self.assertEquals(os.environ.get('HELLO'), 'WORLD')

为了运行测试,做 $ bash run_tests.sh

我解决这个问题的方法是使用 python-dotenv pip 模块。我发现这比必须手动设置然后取消设置测试启动器 shell 脚本中的每个变量更清晰、更易于管理。

首先,运行:

pip install python-dotenv

现在,在项目根目录中创建一个名为 .env.test 的文件,并在其中列出环境变量(每行一个)。例如:

FOO=bar
BAZ=qux

在名为 tests/configuration.py 的文件中,放置以下内容:

from dotenv import load_dotenv, find_dotenv

def setup_testing_environment():
    load_dotenv(find_dotenv(".env.test", raise_error_if_not_found=True))

现在,只要你有一个测试文件,你所要做的就是调用最顶部的configuration.setup_testing_environment()方法来加载你的测试环境变量!

这是一个工作示例 - 创建一个名为 ./tests/test_env_vars.py 的示例测试文件,其中包含以下内容:

import os
import unittest

from tests.configuration import setup_testing_environment

setup_testing_environment()


class TestEnvironmentVars(unittest.TestCase):

    def test_foo_env_var_exists(self):
        self.assertEquals(os.getenv("FOO"), "bar")

    def test_baz_env_var_exists(self):
        self.assertEquals(os.getenv("BAZ"), "qux")