Python 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

我的pytest测试文件分布在多个包中,它们共享一些公共装置。然而,我发现我的自动使用会话范围的装置运行了多次

以下是我的项目的基本结构:

.
├── 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 ========================