Python pytest:防止导入的自动使用的会话装置执行多次
我的pytest测试文件分布在多个包中,它们共享一些公共装置。然而,我发现我的自动使用会话范围的装置运行了多次 以下是我的项目的基本结构:Python pytest:防止导入的自动使用的会话装置执行多次,python,testing,pytest,fixtures,Python,Testing,Pytest,Fixtures,我的pytest测试文件分布在多个包中,它们共享一些公共装置。然而,我发现我的自动使用会话范围的装置运行了多次 以下是我的项目的基本结构: . ├── Pipfile ├── Pipfile.lock ├── __init__.py ├── common │ ├── __init__.py │ └── conftest.py ├── pkg_a │ ├── __init__.py │ ├── conftest.py │ └── test_a.py └── pkg_b
.
├── Pipfile
├── Pipfile.lock
├── __init__.py
├── common
│ ├── __init__.py
│ └── conftest.py
├── pkg_a
│ ├── __init__.py
│ ├── conftest.py
│ └── test_a.py
└── pkg_b
├── __init__.py
├── conftest.py
└── test_b.py
下面是每个.py
文件的内容:
==> ./__init__.py <==
==> ./common/__init__.py <==
==> ./common/conftest.py <==
import pytest
@pytest.fixture(scope='session', autouse=True)
def setup():
print 'setting up'
yield
print 'tearing down'
==> ./pkg_a/__init__.py <==
==> ./pkg_a/conftest.py <==
from common.conftest import *
==> ./pkg_a/test_a.py <==
def test():
assert True
==> ./pkg_b/__init__.py <==
==> ./pkg_b/conftest.py <==
from common.conftest import *
==> ./pkg_b/test_b.py <==
def test_b():
assert True
我对会话装置的理解是,在pytest
命令的生命周期内,它们只运行一次。但是这里的设置
和拆卸
被打印两次,并且它们是交错的
有没有办法只执行一次夹具?我希望设置
在开始时只打印一次,并在整个测试过程的最后一次打印拆卸
另外,我知道参数化会话装置将执行多次。但我不认为我的装置是参数化的。你说得对。会话范围的设备应该只运行一次。但是如果你仔细看,有两个测试装置。一个来自common/conftest.py,另一个来自pkg_a/conftest.py。您不需要在pkg_a/conftest.py中导入common.conftest.py。pytest从项目根开始收集conftest文件。 您可以使用
--setup show
开关查看夹具设置过程:pytest test\u a.py--setup show
要解决您的问题,您可以从test_a(b)/conftest.py文件中删除common.conftest import*中的
关于pytest的conftest集合的更多信息,请参见此处:如果我从pkg_a/conftest.py
中删除import
,则不会为pkg_a
执行夹具。如果我从这两个包中删除import
,则夹具根本不会执行。不打印设置
和拆卸
。我想要的是设置
在一开始就出现,而在最后只会出现一次。项目结构看起来有点配置错误(为什么在项目根目录中有一个\uuu init\uuuuuuuy.py
呢?它是一个包吗?为什么测试目录被制作成包?)。另外,从conftest
s导入是一种不好的做法,因为它很容易破坏东西conftest
s并不意味着是常规python模块,当找到它们时,pytest
将自动执行它们。建议:删除不必要的\uuuu init\uuuu.py
s,删除conftest
导入,将common/conftest.py
移动到项目根目录。@hoefling已理解。谢谢你的建议!是的,我的项目目前的结构有点混乱。我还在想。。。有可能在当前结构下归档夹具吗?@hoefling我认为将测试文件与逻辑代码并排放置是有意义的。我删除了根文件夹中的\uuuuu init\uuuuuu.py
,但结果是一样的。同样,您必须在执行测试的项目根目录中引入conftest.py
,并删除conftest导入。您可以将测试与生产代码一起保存,但在组织代码时必须更加小心pytest
将conftest
文件的父目录附加到sys.path
,这很容易引入导入问题,尤其是在python包中保留测试时。看一看是有意义的,但是根据我的经验,只有当您准备发布带有源代码的测试时,才有意义,比如numpy
或pandas
do。
➜ pytest -s pkg_a pkg_b
========================== test session starts ==========================
platform darwin -- Python 2.7.15, pytest-3.10.0, py-1.7.0, pluggy-0.8.0
rootdir: /path/to/the/project, inifile:
collected 2 items
pkg_a/test_a.py setting up
.
pkg_b/test_b.py setting up
.tearing down
tearing down
======================= 2 passed in 0.02 seconds ========================