Python 在py.test中的每个测试前后运行代码?

Python 在py.test中的每个测试前后运行代码?,python,testing,pytest,test-fixture,Python,Testing,Pytest,Test Fixture,我想在测试套件中的每个测试之前和之后运行额外的安装和拆卸检查。我已经看过了固定装置,但不确定它们是否是正确的方法。我需要在每次测试之前运行设置代码,并且在每次测试之后运行拆卸检查 我的用例是检查没有正确清理的代码:它会留下临时文件。在我的设置中,我会检查文件,在拆卸中,我也会检查文件。如果有额外的文件,我希望测试失败。您可以使用decorators,但要编程,因此不需要在每个方法中都使用decorator 我在下一个代码中假设了几件事: 测试方法的名称如下:“testXXX()” 装饰器被添加到

我想在测试套件中的每个测试之前和之后运行额外的安装和拆卸检查。我已经看过了固定装置,但不确定它们是否是正确的方法。我需要在每次测试之前运行设置代码,并且在每次测试之后运行拆卸检查


我的用例是检查没有正确清理的代码:它会留下临时文件。在我的设置中,我会检查文件,在拆卸中,我也会检查文件。如果有额外的文件,我希望测试失败。

您可以使用decorators,但要编程,因此不需要在每个方法中都使用decorator

我在下一个代码中假设了几件事:

测试方法的名称如下:“testXXX()” 装饰器被添加到实现测试方法的同一模块中

def test1():
    print ("Testing hello world")

def test2():
    print ("Testing hello world 2")

#This is the decorator
class TestChecker(object):
    def __init__(self, testfn, *args, **kwargs):
        self.testfn = testfn

    def pretest(self):
        print ('precheck %s' % str(self.testfn))
    def posttest(self):
        print ('postcheck %s' % str(self.testfn))
    def __call__(self):
        self.pretest()
        self.testfn()
        self.posttest()


for fn in dir() :
    if fn.startswith('test'):
        locals()[fn] = TestChecker(locals()[fn])
现在如果你调用测试方法

test1()
test2()
输出应该类似于:

precheck <function test1 at 0x10078cc20>
Testing hello world
postcheck <function test1 at 0x10078cc20>
precheck <function test2 at 0x10078ccb0>
Testing hello world 2
postcheck <function test2 at 0x10078ccb0>
调用
TestClass.my_test()
将打印:

precheck <bound method type.my_test of <class '__main__.TestClass'>>
Testing from class method 
postcheck <bound method type.my_test of <class '__main__.TestClass'>>
预检查
基于类方法的测试
事后检查

py。测试夹具在技术上是达到您的目的的适当方法

您只需要这样定义一个装置:

@pytest.fixture(autouse=True)
def run_around_tests():
    # Code that will run before your test, for example:
    files_before = # ... do something to check the existing files
    # A test function will be run at this point
    yield
    # Code that will run after your test, for example:
    files_after = # ... do something to check the existing files
    assert files_before == files_after
通过使用
autouse=True
声明fixture,它将自动为同一模块中定义的每个测试功能调用


也就是说,有一个警告。在安装/拆卸时断言是一种有争议的做法。我的印象是py.test的主要作者不喜欢它(我也不喜欢它,因此这可能会影响我自己的看法),因此在前进的过程中,您可能会遇到一些问题或粗糙的边缘。

您可以使用Pytest的模块级设置/拆卸夹具

这是链接

其工作原理如下:

 def setup_module(module):
     """ setup any state specific to the execution of the given module."""

 def teardown_module(module):
     """ teardown any state that was previously setup with a setup_module
     method."""

 Test_Class():
        def test_01():
          #test 1 Code
它将在本测试之前调用
setup_模块
,在测试完成后调用
teardown_模块

您可以在每个测试脚本中包含此装置,以便为每个测试运行它

如果您想使用目录中所有测试通用的东西,可以使用包/目录级别的框架

在包的
\uuuu init\uuuuu.py
文件中,可以包含以下内容

     def setup_package():
       '''Set up your environment for test package'''

     def teardown_package():
        '''revert the state '''

固定装置正是你想要的。 这就是它们的设计目的

您是使用pytest样式的装置,还是使用设置拆卸(模块、类或方法级别)xUnit样式的装置,取决于环境和个人喜好

从您描述的内容来看,似乎您可以使用。
或xUnit样式的功能级别


Pytest已经完全覆盖了您。如此之多以至于它可能是一条信息消防水带。

默认情况下,固定装置具有
scope=function
。所以,如果你只是使用一个定义,比如

@pytest.fixture
def fixture_func(self)
它默认为
(scope='function')

因此,fixture函数中的任何finalize都将在每次测试后调用

参考:
1.

您可以使用
夹具
来实现您想要的

导入pytest
@pytest.fixture(autouse=True)
def在测试前和测试后运行(tmpdir):
“”“运行测试前后执行断言的装置”“”
#设置:填充您想要的任何逻辑
产量#这是测试的地方
#拆卸:填充任何您想要的逻辑
详细说明
  • @pytest.fixture(autouse=True)
    ,:“有时,您可能希望在不显式声明函数参数或usefixtures装饰器的情况下自动调用fixture。”因此,每次执行测试时,此fixture都将运行

  • #设置:填充您想要的任何逻辑
    ,此逻辑将在实际运行每个测试之前执行。在您的情况下,您可以添加将在实际测试之前执行的断言语句

  • yield
    ,如注释中所示,这是进行测试的地方

  • #拆卸:填充您想要的任何逻辑
    ,此逻辑将在每次测试后执行。该逻辑保证运行,而不管过程中发生了什么 测试

  • 注意:
    pytest
    中,测试失败和执行测试时出错是有区别的。失败表示测试以某种方式失败。 错误表明您无法进行正确的测试

    考虑以下示例:

    运行测试前断言失败->错误
    导入pytest
    @pytest.fixture(autouse=True)
    def运行测试():
    assert False#这将在运行测试时生成错误
    产量
    断言正确
    def test():
    断言正确
    
    运行测试后断言失败->错误
    导入pytest
    @pytest.fixture(autouse=True)
    def运行测试():
    断言正确
    产量
    断言错误
    def test():
    断言正确
    
    测试失败->失败
    导入pytest
    @pytest.fixture(autouse=True)
    def运行测试():
    断言正确
    产量
    断言正确
    def test():
    断言失败
    
    测试通过->通过
    导入pytest
    @pytest.fixture(autouse=True)
    def运行测试():
    断言正确
    产量
    断言正确
    def test():
    断言正确
    
    这看起来可能适用于免费功能。我也有类功能(虽然我正在尝试摆脱所有的测试类)。它也适用于类方法,我已经更新了我的答案。有人成功地在一个有固定装置的测试函数上运行了装饰器吗?阅读@Augustinalville评论的人注意:答案已经编辑过,现在是pytest 3.0的最新版本。固定装置是官方支持的。断言不应该在装置内部进行。这不是最好的做法。回答得很好。参考链接断了。
    @pytest.fixture
    def fixture_func(self)