我有一堆使用pytest编写的测试。目录dir
下都有。例如:
dir/test_base.py
dir/test_something.py
dir/test_something2.py
...
其中的简化版代码如下:
test_base.py
import pytest
class TestBase:
def setup_module(module):
assert False
def teardown_module(module):
assert False
test_something.py
import pytest
from test_base import TestBase
class TestSomething(TestBase):
def test_dummy():
pass
test_something2.py
import pytest
from test_base import TestBase
class TestSomethingElse(TestBase):
def test_dummy2():
pass
我的所有test_something*.py
文件都扩展了test_base.py
中的基类。现在我在setup_module(module)
中编写了teardown_module(module)
和test_base.py
方法。我期待为所有测试调用一次setup_module,并在完成所有测试后在最后调用teardown_module()
。
但这些功能似乎没有被调用?我需要一些装饰器吗?
答案 0 :(得分:4)
将setup_module
和teardown_module
置于模块级别的课程之外。然后在测试中添加您的课程。
def setup_module(module):
"""..."""
def teardown_module(module):
"""..."""
class TestSomething:
def test_dummy(self):
"""do some tests"""
有关详细信息,请参阅this article。
答案 1 :(得分:4)
OP的要求是设置和拆除每个只执行一次,而不是每个模块执行一次。这可以通过组合 conftest.py 文件, @ pytest.fixture(scope =“session”)并将夹具名称传递给每个测试函数来实现。< / p>
中描述了这些内容以下是一个例子:
<强> conftest.py 强>
import pytest
@pytest.fixture(scope="session")
def my_setup(request):
print '\nDoing setup'
def fin():
print ("\nDoing teardown")
request.addfinalizer(fin)
<强> test_something.py 强>
def test_dummy(my_setup):
print '\ntest_dummy'
<强> test_something2.py 强>
def test_dummy2(my_setup):
print '\ntest_dummy2'
def test_dummy3(my_setup):
print '\ntest_dummy3'
运行py.test -s时的输出:
collected 3 items
test_something.py
Doing setup
test_dummy
.
test_something2.py
test_dummy2
.
test_dummy3
.
Doing teardown
名称 conftest.py 很重要:你不能给这个文件一个不同的名字,并期望Pytest找到它作为灯具的来源。
设置 scope =“session”非常重要。否则,将对每个测试模块重复设置和拆卸。
如果您不想将夹具名称 my_setup 作为参数ti eacg测试函数传递,则可以将测试函数放在类中并将pytest.mark.usefixtures * decorator应用于类。
答案 2 :(得分:1)
setup_module / teardown_module。这也允许自定义设置。如果您只有一个setup_module,可以将它放到test_base.py并从其他位置导入它。 HTH。
答案 3 :(得分:0)
首先,将所有测试放在名为“tests”的模块中是一种很好的做法:
<product>
...
tests/
__init__.py
test_something.py
其次我认为你应该在你的基类中使用setup_class / teardown_class方法:
import unittest
class MyBase(unittest.TestCase):
@classmethod
def setup_class(cls):
...
@classmethod
def teardown_class(cls):
...