在pytest中使用conftest进行设置/清理
我有不同的测试文件夹(包)。我想为特定的包(文件夹)设置一些数据,并在测试结束后清理这些数据。
问题是,set_up()
在运行该文件夹的测试用例之前执行,但在运行完所有测试用例后,tear_down
并没有执行。它是在运行完其他包(文件夹)的所有测试用例后才执行的(也就是在整个pytest会话结束后)。
[conftest.py]
@pytest.fixture(scope="session", autouse=True)
def set_up(request):
'''Test package setup'''
def tear_down():
'''Test package teardown'''
每个文件夹里都有一个 __init__.py
文件,这个是显而易见的。
那么我该如何在运行完该文件夹的所有测试用例后,立即执行 tear_down()
呢?因为我知道:scope="module"
在这种情况下是没用的,因为我并不想为每个测试都设置和清理。
任何帮助都非常感谢。
谢谢。
2 个回答
conftest.py
文件是用来配置整个目录(可以理解为“包”)的。如果你在测试的根目录放一个这样的文件,它里面的会话范围的“夹具”(也就是一些准备工作)会在这个范围开始时运行,而对应的 tear_down
(清理工作)会等到这个范围结束后再执行,也就是等整个测试会话结束后再做清理。如果你需要创建只在子目录(子包)中使用的夹具,就需要在那些子目录里再放一个 conftest.py
文件,并在里面定义自己的 scope='session'
的夹具。一个常见的例子是向数据库添加数据。想象一下,你想在对应的测试包中为所有测试填充你的 purchases
数据库表格,你就可以把执行这个任务的夹具放在 tests.purchases.conftest.py
文件里。
shopping_app/
tests/
__init__.py
conftest.py # applies to all tests
buyers/
products/
purchases/
conftest.py # only applies to this scope and sub-scopes
__init__.py
test1.py
test2.py
payments/
refunds/
sellers/
stores/
在 tests.purchases.conftest.py
文件里,你会有普通的夹具声明。比如,一个用于预填充和删除数据库表格行的 set_up/tear_down 组合,可能看起来像这样:
@pytest.fixture(scope='session', autouse=True)
def prep_purchases(db, data):
# set_up: fill table at beginning of scope
populate_purchase_table_with_data(db, data)
# yield, to let all tests within the scope run
yield
# tear_down: then clear table at the end of the scope
empty_purchase_table(db)
有些夹具不需要明确地注入到测试中(我们只关心它们的副作用,而不是它们的返回值),这就是 autouse
参数的作用。至于使用 yield
的 set_up/tear_down 的上下文管理器语法,如果你对这个不太熟悉,也可以把 tear_down
部分单独写成一个函数。
pytest 并不直接支持包级别的固定装置(fixtures)。unittest 也是如此。
在主要的测试框架中,我认为 nose 是唯一支持包级固定装置的框架。不过,nose2 正在取消对包级固定装置的支持。具体可以查看 nose2 的文档。
pytest 支持 模块、函数、类和方法级别的固定装置,这些都是 xunit 风格的固定装置。