Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果夹具中存在异常,Pytest类级别的夹具将为每个方法运行_Python_Pytest - Fatal编程技术网

Python 如果夹具中存在异常,Pytest类级别的夹具将为每个方法运行

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

我正在使用pytest编写一些测试,它需要一个环境变量来运行测试函数。因此,我创建了一个fixture,它将检查环境变量是否存在或是否退出。下面是我的代码

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