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

     2023-02-16     266

关键词:

【中文标题】在 py.test 中的每个测试之前和之后运行代码?【英文标题】:Run code before and after each test in py.test? 【发布时间】:2014-05-02 21:17:49 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

py.test 固定装置是实现您的目的的技术上足够的方法。

你只需要像这样定义一个fixture:

@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 的主要作者不喜欢它(我也不喜欢它,所以这可能会影响我自己的看法),所以你在前进时可能会遇到一些问题或粗糙的边缘。

【讨论】:

阅读@AugustinLaville 评论的人的注意事项:答案已经过编辑,现在是最新的 从 pytest 3.0 开始,正式支持产生内部固定装置。 docs.pytest.org/en/latest/yieldfixture.html 断言不应该在固定装置内完成。这不是最佳做法。 非常好的答案【参考方案2】:

您可以使用fixture 来实现您想要的。

import pytest

@pytest.fixture(autouse=True)
def run_before_and_after_tests(tmpdir):
    """Fixture to execute asserts before and after a test is run"""
    # Setup: fill with any logic you want

    yield # this is where the testing happens

    # Teardown : fill with any logic you want

详细说明

    @pytest.fixture(autouse=True), from the docs: “有时,您可能希望在不显式声明函数参数或 usefixtures 装饰器的情况下自动调用夹具。” 因此,此夹具每次都会运行执行测试。

    # Setup: fill with any logic you want,这个逻辑将在每个测试实际运行之前执行。在您的情况下,您可以添加将在实际测试之前执行的断言语句。

    yield,如评论中所示,这是进行测试的地方

    # Teardown : fill with any logic you want,每次测试后都会执行这个逻辑。无论在 测试。

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

考虑以下示例:

在测试运行之前断言失败 -> 错误

import pytest


@pytest.fixture(autouse=True)
def run_around_tests():
    assert False # This will generate an error when running tests
    yield
    assert True

def test():
    assert True

测试运行后断言失败 -> 错误

import pytest


@pytest.fixture(autouse=True)
def run_around_tests():
    assert True
    yield
    assert False

def test():
    assert True

测试失败 -> 失败

import pytest


@pytest.fixture(autouse=True)
def run_around_tests():
    assert True
    yield
    assert True

def test():
    assert Fail

测试通过 -> PASSED

import pytest


@pytest.fixture(autouse=True)
def run_around_tests():
    assert True
    yield
    assert True

def test():
    assert True

【讨论】:

【参考方案3】:

夹具正是您想要的。 这就是它们的设计目的。

您是使用 pytest 样式的固定装置,还是 setupteardown(模块、类或方法级别)xUnit 样式的固定装置,取决于环境和个人品味。

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

Pytest 完全覆盖了你。如此之多,以至于它可能是信息的消防水带。

【讨论】:

【参考方案4】:

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

这是链接

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

它的工作原理如下:

 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_module,在测试完成后调用teardown_module

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

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

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

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

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

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

【讨论】:

【参考方案5】:

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

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

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

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

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)))

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

【讨论】:

这看起来可能适用于免费功能。我也有类功能(虽然我试图摆脱所有的测试类)。 它也适用于类方法,我已经更新了我的答案。 有人成功地在一个有固定装置的测试函数上运行装饰器吗?【参考方案6】:

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

@pytest.fixture
def fixture_func(self)

默认为(scope='function')

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

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

【讨论】:

参考链接已损坏。【参考方案7】:

这是一个老问题,但我个人从docs 中找到了另一种方法: 使用pytest.ini 文件:

[pytest]
usefixtures = my_setup_and_tear_down
import pytest

@pytest.fixture
def my_setup_and_tear_down():

    # SETUP
    # Write here the logic that you need for the setUp

    yield # this statement will let the tests execute

    # TEARDOWN 
    # Write here the logic that you need after each tests

关于 yield 语句以及它如何允许运行测试:HERE

【讨论】:

PHPUnit -setUp() - 它在每个测试用例之前和之后运行吗?

...布时间】:2016-01-0704:35:01【问题描述】:我还是对PHPUnit中的setup()有点困惑。它是否在之前和之后每个测试用例运行?例如,我想在每次测试之前清理我的文章表,但我想保留我已经注入表中的测试数据。因为我只想在下次测试... 查看详情

testng注解使用(代码片段)

...一个测试方法后,该方法被调用@BeforeTest 是针对xml文件中的test标签进行操作,在xml中的每一个test标签执行前运行@AfterTest 是针对xml文件中的test标签进行操作,在xml中的每一个test标签执行后运行1.1代码示例1publicclassBasicAnnotince... 查看详情

如何在每个测试方法之前和之后执行sql脚本

】如何在每个测试方法之前和之后执行sql脚本【英文标题】:Howtoexecutesqlscriptbeforeandaftereachtestmethod【发布时间】:2020-10-2521:55:49【问题描述】:spring中有一个@Sql注解,允许在测试方法前后执行sql代码:@Test@Sql("init.sql")@Sql(scripts=... 查看详情

py.test 混合夹具和异步协程

...syncio的postgres接口)访问Postgresql数据库。我的主要期望:每个测试用例都应该可以访问一个新的异步事件循环。运行时间过长的测试会因超时异常 查看详情

在 Jest 中的每个测试之前运行全局测试设置

】在Jest中的每个测试之前运行全局测试设置【英文标题】:RunningaglobaltestsetupbeforeeachtestinJest【发布时间】:2018-07-2105:35:51【问题描述】:我正在尝试在我的Jest测试套件中的每个测试之前执行测试设置功能。我知道我可以使用bef... 查看详情

如何在spring boot中的每个测试类之后销毁和重新创建bean

】如何在springboot中的每个测试类之后销毁和重新创建bean【英文标题】:Howtodestroyandrecreatebeanaftereachtestclassinspringboot【发布时间】:2017-04-1920:45:56【问题描述】:我有一个应用程序,我创建beanA来安排配置中定义的任务,但在测... 查看详情

测试代码是不是从 py.test 会话中执行

】测试代码是不是从py.test会话中执行【英文标题】:Testifcodeisexecutedfromwithinapy.testsession测试代码是否从py.test会话中执行【发布时间】:2014-10-0100:36:55【问题描述】:如果我的代码在py.test下运行,我想连接到不同的数据库。是否... 查看详情

如何配置 PyCharm 以运行 py.test 测试?

】如何配置PyCharm以运行py.test测试?【英文标题】:HowdoIconfigurePyCharmtorunpy.testtests?【发布时间】:2011-09-1719:57:09【问题描述】:我想开始为我的Python代码编写单元测试,py.test框架听起来比Python捆绑的unittest更好。所以我在我的项... 查看详情

junit学习(代码片段)

...16指示一个测试用例1718@Before+方法:19表示该方法必须在每个测试之前运行,一遍测试某些先决条件(注意:每个测试用例之前)2021@BeforeClass+方法:22指示附着的静态方法,在所有的测试之前必须运行一次,发生这种情况时一般... 查看详情

pytest测试用例介绍

....py的内容如下:test_b.py的内容如下:如果希望执行test_a.py中的两个测试用例,可以使用下面的命令:如果希望执行test_a.py和test_b.py中的所有测试用例,可以使用下面的命令:如果希望仅执行test_a.py中的test_case_a_1测试用例,可以... 查看详情

在每个请求之前和之后运行的 PHP 函数或文件

】在每个请求之前和之后运行的PHP函数或文件【英文标题】:PHPfunctionorfiletorunbeforeandaftereveryrequest【发布时间】:2009-12-2104:28:47【问题描述】:我想知道是否有一种方法可以指定每次用户访问和退出我网站上的页面时要调用的php... 查看详情

springboot中的测试(test)

SpringBoot2.2之后用的Junit5,所以在这里使用的Junit5。SpringBoot会默认帮我们导入包,所以不用添加依赖了。注解:@BeforeAll:只执行一次,执行时机是在所有测试和@BeforeEach注解方法之前。@BeforeEach:在每个测试执行之前执行。@AfterEach:... 查看详情

pytest之框架结构及运行方式

...结果显示如下:test7.py::test_function1整个模块.py开始不在类中的函数前不在类中的函数1PASSED不在类中的函数后test7.py::test_function2不在类中的函数前不在类中的函数2PASSED不在类中的函数后test7.py::TestXase::test_method1我是类开始执行我... 查看详情

MbUnit:在所有夹具运行后运行代码

...nit具有可以应用于应该运行的方法的属性:[FixtureSetUp]-在每个灯具之前[FixtureTearDown]-在每个夹具之后[设置]-每次测试之前[TearDown]-每次测试后 查看详情

使用 Test::Unit,如何在所有测试(但不是每个测试)之前运行一些代码?

】使用Test::Unit,如何在所有测试(但不是每个测试)之前运行一些代码?【英文标题】:WithTest::Unit,howcanIrunabitofcodebeforealltests(butnoteachtest)?【发布时间】:2011-10-1116:36:31【问题描述】:在我使用test::unit的测试应用程序中,我需... 查看详情

成功运行 py.test 后模块“线程”中的 KeyError

】成功运行py.test后模块“线程”中的KeyError【英文标题】:KeyErrorinmodule\'threading\'afterasuccessfulpy.testrun【发布时间】:2012-02-0504:38:14【问题描述】:我正在使用py.test运行一组测试。他们通过。伊皮!但我收到了这条消息:ExceptionK... 查看详情

如果定义了构造函数,py.test 会跳过测试类

】如果定义了构造函数,py.test会跳过测试类【英文标题】:py.testskipstestclassifconstructorisdefined【发布时间】:2014-02-2105:53:18【问题描述】:我有以下通过py.test运行的单元测试代码。构造函数的存在使整个类在运行时跳过py.test-v-s... 查看详情

html在ckeditorinitilize之前和之后运行代码(代码片段)

查看详情