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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22627659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 01:18:38  来源:igfitidea点击:

Run code before and after each test in py.test?

pythontestingpytesttest-fixture

提问by edA-qa mort-ora-y

I want to run additional setup and teardown checks before and after each test in my test suite. I've looked at fixtures but not sure on whether they are the correct approach. I need to run the setup code prior to each test and I need to run the teardown checks after each test.

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

My use-case is checking for code that doesn't cleanup correctly: it leaves temporary files. In my setup I will check the files and in the teardown I also check the files. If there are extra files I want the test to fail.

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

回答by Roberto

You may use decorators but programatically, so you don't need to put the decorator in each method.

您可以以编程方式使用装饰器,因此您不需要将装饰器放在每个方法中。

I'm assuming several things in next code:

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

The test methods are all named like: "testXXX()" The decorator is added to the same module where test methods are implemented.

测试方法都命名为:“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])

Now if you call the test methods...

现在,如果您调用测试方法...

test1()
test2()

The output should be something like:

输出应该是这样的:

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>

If you have test methods as class methods, the approach is also valid. For instance:

如果您将测试方法作为类方法,则该方法也是有效的。例如:

class TestClass(object):
    @classmethod
    def my_test(cls):
        print ("Testing from class method")

for fn in dir(TestClass) :
    if not fn.startswith('__'):
        setattr(TestClass, fn, TestChecker(getattr(TestClass, fn)))

The call to TestClass.my_test()will print:

调用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'>>

回答by tawmas

py.test fixtures are a technically adequate method to achieve your purpose.

py.test fixtures 是一种技术上足够的方法来实现你的目的。

You just need to define a fixture like that:

你只需要定义一个这样的夹具:

@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

By declaring your fixture with autouse=True, it will be automatically invoked for each test function defined in the same module.

通过使用 声明您的夹具autouse=True,它将为同一模块中定义的每个测试函数自动调用。

That said, there is one caveat. Asserting at setup/teardown is a controversial practice. I'm under the impression that the py.test main authors do not like it (I do not like it either, so that may colour my own perception), so you might run into some problems or rough edges as you go forward.

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

回答by Arvind

You can use Module level setup/teardown Fixtures of Pytest.

您可以使用 Pytest 的模块级设置/拆卸装置。

Here's the Link

这是链接

http://pytest.org/latest/xunit_setup.html

http://pytest.org/latest/xunit_setup.html

It Works as follows:

它的工作原理如下:

 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

It will call setup_modulebefore this test and teardown_moduleafter test completes.

它将setup_module在此测试之前和teardown_module测试完成后调用。

You can include this fixture in each test-script to run it for each test.

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

IF you want to use something that is common to all tests in a directory You can use package/directory level fixtures nose framework

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

http://pythontesting.net/framework/nose/nose-fixture-reference/#package

http://pythontesting.net/framework/nose/nose-fixture-reference/#package

In __init__.pyfile of the package you can include following

__init__.py包的文件中,您可以包含以下内容

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

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

回答by Okken

Fixtures are exactly what you want. That's what they are designed for.

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

Whether you use pytest style fixtures, or setupand teardown(module, class, or method level) xUnit style fixtures, depends on the circumstance and personal taste.

无论您使用pytest 风格的装置,还是设置拆卸(模块、类或方法级别)xUnit 风格的装置,都取决于环境和个人品味。

From what you are describing, it seems like you could use pytest autouse fixtures.
Or xUnit style function level setup_function()/teardown_function().

根据您的描述,您似乎可以使用pytest autouse fixtures
或者 xUnit 风格的函数级别setup_function()/teardown_function()

Pytest has you completely covered. So much so that perhaps it's a fire hose of information.

Pytest 已完全涵盖您。如此之多以至于它可能是信息的消防水带。

回答by alpha_989

Fixtures by default have scope=function. So, if you just use a definition such as

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

@pytest.fixture
def fixture_func(self)

It defaults to (scope='function').

它默认为(scope='function').

So any finalizes in the fixture function will be called after each test.

因此,在每次测试后都会调用夹具函数中的任何终结。

Ref: 1. http://programeveryday.com/post/pytest-creating-and-using-fixtures-for-streamlined-testing/

参考:1. http://programeveryday.com/post/pytest-creating-and-using-fixtures-for-streamlined-testing/