Python 如果夹具中存在异常,Pytest类级别的夹具将为每个方法运行
我正在使用pytest编写一些测试,它需要一个环境变量来运行测试函数。因此,我创建了一个fixture,它将检查环境变量是否存在或是否退出。下面是我的代码Python 如果夹具中存在异常,Pytest类级别的夹具将为每个方法运行,python,pytest,Python,Pytest,我正在使用pytest编写一些测试,它需要一个环境变量来运行测试函数。因此,我创建了一个fixture,它将检查环境变量是否存在或是否退出。下面是我的代码 import os import sys import pytest from ..factorial import fact @pytest.fixture(scope='class') def pre(request): print('************setting up************') pw
import os
import sys
import pytest
from ..factorial import fact
@pytest.fixture(scope='class')
def pre(request):
print('************setting up************')
pwd = os.environ.get('PASSWD', None)
if pwd is not None:
request.cls.pwd = pwd
else:
sys.exit('This test requires your password, '
'please run export PASSWD=<yourPassword>')
@pytest.mark.usefixtures('pre')
class TestFactorial:
def test_postive(self):
assert fact(5) == 120
def test_false(self):
assert fact(6) == 720
现在,如果未设置环境变量,则整个装置将运行两次。下面是输出
collected 2 items
test_factorial.py ************setting up************
E************setting up************
E
====================================================================================================== ERRORS ======================================================================================================
___________________________________________________________________________________ ERROR at setup of TestFactorial.test_postive ___________________________________________________________________________________
request = <SubRequest 'pre' for <Function test_postive>>
@pytest.fixture(scope='class')
def pre(request):
print('************setting up************')
pwd = os.environ.get('PASSWD', None)
if pwd is not None:
request.cls.pwd = pwd
else:
> sys.exit('This test requires your password, '
'please run export PASSWD=<yourPassword>')
E SystemExit: This test requires your password, please run export PASSWD=<yourPassword>
test_factorial.py:17: SystemExit
____________________________________________________________________________________ ERROR at setup of TestFactorial.test_false ____________________________________________________________________________________
request = <SubRequest 'pre' for <Function test_false>>
@pytest.fixture(scope='class')
def pre(request):
print('************setting up************')
pwd = os.environ.get('PASSWD', None)
if pwd is not None:
request.cls.pwd = pwd
else:
> sys.exit('This test requires your password, '
'please run export PASSWD=<yourPassword>')
E SystemExit: This test requires your password, please run export PASSWD=<yourPassword>
test_factorial.py:17: SystemExit
设置环境变量时的输出
pytest -sq test_factorial.py
************setting up************
67
..
2 passed in 0.01 seconds
所以它只为班级运行了一次
未设置环境变量时的输出
pytest -sq test_factorial.py
************setting up************
69
E************setting up************
82
E
====================================================================================================== ERRORS ======================================================================================================
___________________________________________________________________________________ ERROR at setup of TestFactorial.test_postive ___________________________________________________________________________________
request = <SubRequest 'pre' for <Function test_postive>>
@pytest.fixture(scope='class')
def pre(request):
print('************setting up************')
pwd = os.environ.get('PASSWD', None)
if pwd is not None:
print(randint(1, 100))
request.cls.pwd = randint(1, 100)
else:
print(randint(1, 100))
> sys.exit('This test requires your password, '
'please run export PASSWD=<yourPassword>')
E SystemExit: This test requires your password, please run export PASSWD=<yourPassword>
test_factorial.py:20: SystemExit
____________________________________________________________________________________ ERROR at setup of TestFactorial.test_false ____________________________________________________________________________________
request = <SubRequest 'pre' for <Function test_false>>
@pytest.fixture(scope='class')
def pre(request):
print('************setting up************')
pwd = os.environ.get('PASSWD', None)
if pwd is not None:
print(randint(1, 100))
request.cls.pwd = randint(1, 100)
else:
print(randint(1, 100))
> sys.exit('This test requires your password, '
'please run export PASSWD=<yourPassword>')
E SystemExit: This test requires your password, please run export PASSWD=<yourPassword>
test_factorial.py:20: SystemExit
2 error in 0.03 seconds
pytest-sq-test\u factorial.py
************设置************
69
E**********设置************
82
E
============================================================================================================================================================错误======================================================================================================
___________________________________________________________________________________设置TestFactorial.test\u positive时出错___________________________________________________________________________________
请求=
@pytest.fixture(scope='class')
def预处理(请求):
打印(“*************设置*******************”)
pwd=os.environ.get('PASSWD',None)
如果pwd不是无:
打印(randint(1100))
request.cls.pwd=randint(1100)
其他:
打印(randint(1100))
>sys.exit('此测试需要您的密码,'
'请运行导出密码=')
E SystemExit:此测试需要您的密码,请运行导出密码=
测试因子py:20:SystemExit
____________________________________________________________________________________TestFactorial.test\u设置时出错false____________________________________________________________________________________
请求=
@pytest.fixture(scope='class')
def预处理(请求):
打印(“*************设置*******************”)
pwd=os.environ.get('PASSWD',None)
如果pwd不是无:
打印(randint(1100))
request.cls.pwd=randint(1100)
其他:
打印(randint(1100))
>sys.exit('此测试需要您的密码,'
'请运行导出密码=')
E SystemExit:此测试需要您的密码,请运行导出密码=
测试因子py:20:SystemExit
0.03秒内发生2次错误
注意,每种情况下打印的随机数是不同的,因此这表明fixture实际上触发了两次,类中每个方法触发一次
这是非常奇怪的行为。有什么线索吗?pytest捕捉到了
SystemExit
异常,仔细想想,这是合理的:如果您正在测试一个碰巧调用sys.exit
的函数,您不会希望它关闭整个测试套件
使用
pytest.exit
而不是sys.exit
,这会向pytest发出信号,表示您想真正关闭测试套件。我可以通过在夹具内部使用pytest.skip
来获得所需的结果。这样,如果夹具抛出一些异常,那么使用夹具的测试将被跳过。这是可以理解的,但是为什么当pytest捕获到异常时,夹具运行了两次,这就是我更好奇的地方。据pytest所知,第一次实例化夹具的尝试崩溃了,因此它实际上并没有初始化。所以它需要初始化它,这意味着再次运行该函数。为什么要两次?因为有两个测试。pytest尝试运行第一个,但尝试失败。它没有意识到问题在于整个类,因此它盲目地再次尝试进行第二次测试。。有道理。。谢谢
pytest -sq test_factorial.py
************setting up************
67
..
2 passed in 0.01 seconds
pytest -sq test_factorial.py
************setting up************
69
E************setting up************
82
E
====================================================================================================== ERRORS ======================================================================================================
___________________________________________________________________________________ ERROR at setup of TestFactorial.test_postive ___________________________________________________________________________________
request = <SubRequest 'pre' for <Function test_postive>>
@pytest.fixture(scope='class')
def pre(request):
print('************setting up************')
pwd = os.environ.get('PASSWD', None)
if pwd is not None:
print(randint(1, 100))
request.cls.pwd = randint(1, 100)
else:
print(randint(1, 100))
> sys.exit('This test requires your password, '
'please run export PASSWD=<yourPassword>')
E SystemExit: This test requires your password, please run export PASSWD=<yourPassword>
test_factorial.py:20: SystemExit
____________________________________________________________________________________ ERROR at setup of TestFactorial.test_false ____________________________________________________________________________________
request = <SubRequest 'pre' for <Function test_false>>
@pytest.fixture(scope='class')
def pre(request):
print('************setting up************')
pwd = os.environ.get('PASSWD', None)
if pwd is not None:
print(randint(1, 100))
request.cls.pwd = randint(1, 100)
else:
print(randint(1, 100))
> sys.exit('This test requires your password, '
'please run export PASSWD=<yourPassword>')
E SystemExit: This test requires your password, please run export PASSWD=<yourPassword>
test_factorial.py:20: SystemExit
2 error in 0.03 seconds