为什么unittest.TestCase无法识别我的py.test固定装置?
我正在尝试在我的单元测试中使用 py.test
的 fixtures,并且是和 unittest
一起使用的。我把几个 fixtures 放在项目顶层的一个 conftest.py
文件里(具体做法可以参考 这里),用 @pytest.fixture
装饰它们,并把它们的名字作为需要的测试函数的参数。
这些 fixtures 注册得很正确,像通过 py.test --fixtures test_stuff.py
命令可以看到,但当我运行 py.test
时,却出现了 NameError: global name 'my_fixture' is not defined
的错误。这个问题似乎只在我使用 unittest.TestCase
的子类时出现——不过 py.test
的文档似乎说它和 unittest
是兼容的。
为什么在我使用 unittest.TestCase
时,测试看不到这些 fixtures 呢?
不工作:
conftest.py
@pytest.fixture
def my_fixture():
return 'This is some fixture data'
test_stuff.py
import unittest
import pytest
class TestWithFixtures(unittest.TestCase):
def test_with_a_fixture(self, my_fixture):
print(my_fixture)
工作:
conftest.py
@pytest.fixture()
def my_fixture():
return 'This is some fixture data'
test_stuff.py
import pytest
class TestWithFixtures:
def test_with_a_fixture(self, my_fixture):
print(my_fixture)
我问这个问题更多是出于好奇;目前我只是完全放弃了 unittest
。
3 个回答
把这个“固定装置”定义成一个可以访问的变量,就像下面例子中的
input
一样。定义的方法是用request.cls.VARIABLE_NAME_YOU_DEFINE = RETURN_VALUE
。在单元测试类外部,使用
@pytest.mark.usefixtures("YOUR_FIXTURE")
来使用这个“固定装置”;在单元测试类内部,可以通过self.VARIABLE_NAME_YOU_DEFINE
来访问这个“固定装置”。
例如:
import unittest
import pytest
@pytest.fixture(scope="class")
def test_input(request):
request.cls.input = {"key": "value"}
@pytest.mark.usefixtures("test_input")
class MyTestCase(unittest.TestCase):
def test_something(self):
self.assertEqual(self.input["key"], "value")
你可以在 unittest.TestCase
中使用 pytest 的一些工具,叫做 fixtures,并且可以通过 pytest 的选项 autouse
来自动使用它们。不过,如果你在使用这些工具的单元测试方法中用上了 test_
前缀,就会出现以下错误:
Fixtures are not meant to be called directly,...
### conftest.py
@pytest.fixture
def my_fixture():
return 'This is some fixture data'
一个解决办法是使用一个叫 prepare_fixture
的方法,把这些工具设置为 TestWithFixtures
类的属性,这样所有的单元测试方法都能使用这些工具。
### test_stuff.py
import unittest
import pytest
class TestWithFixtures(unittest.TestCase):
@pytest.fixture(autouse=True)
def prepare_fixture(self, my_fixture):
self.myfixture = my_fixture
def test_with_a_fixture(self):
print(self.myfixture)
虽然pytest支持通过测试函数的参数来接收一些准备好的数据(叫做fixtures),但对于unittest的测试方法来说,它们不能直接接收这些准备好的数据。这是因为这样做可能会影响到运行普通的unittest测试套件的能力。
更多信息可以参考下面的链接: https://pytest.org/en/latest/unittest.html
其实也可以在unittest.TestCase
中使用这些准备好的数据。想了解更多,可以查看那个页面。