zoukankan      html  css  js  c++  java
  • pytest 内置和自定义marker

    pytest 内置和自定义marker

    可以通过命令行查看所有marker,包括内置和自定义的

    pytest --markers
    

    内置marker包括usefixtures 、filterwarnings 、skip 、skipif 、xfail这5个。参数化的marker在pytest参数化中有介绍,hook的marker在pytest hook中,插件的marker(pytest-ordering、allure等)在pytest插件中。当前只需知道有以上这些分类的marker即可

    内置 marker

    • usefixtures:

    如果我们只想把fixture注入到test中,test不直接访问fixture的时候,就需要用到usefixtures。
    示例,test需要一个临时目录,但是并不需要知道这个目录具体路径在哪

    # content of conftest.py
    import os
    import shutil
    import tempfile
    
    import pytest
    
    @pytest.fixture
    def cleandir():
        old_cwd = os.getcwd()
        newpath = tempfile.mkdtemp()
        os.chdir(newpath)
        yield
        os.chdir(old_cwd)
        shutil.rmtree(newpath)
    
    # content of test_setenv.py
    import os
    
    import pytest
    
    
    @pytest.mark.usefixtures("cleandir")
    class TestDirectoryInit:
        def test_cwd_starts_empty(self):
            assert os.listdir(os.getcwd()) == []
    
        with open("myfile", "w") as f:
            f.write("hello")
    
        def test_cwd_again_starts_empty(self):
            assert os.listdir(os.getcwd()) == []
    

    TestDirectoryInit的测试方法需要一个临时目录作为当前工作目录,在类上添加@pytest.mark.usefixtures("cleandir"),类的方法不加fixture也能有"cleandir"的效果。

    usefixtures可以添加多个fixture

    @pytest.mark.usefixtures("cleandir", "anotherfixture")
    

    usefixtures可以用在pytestmark,作用域是定义所在module的所有tests

    pytestmark = pytest.mark.usefixtures("cleandir")
    

    usefixtures也可以用在pytest.ini,作用域是整个项目的所有tests

    # content of pytest.ini
    [pytest]
    usefixtures = cleandir
    

    不过需要注意的是fixture函数本身是不能用usefixtures的,如果想要嵌套fixture,只能通过在fixture修饰的函数中,添加参数这种方式。

    • filterwarnings
      过滤警告信息。
      示例,api_v1()抛出了“api v1”的警告,test_one()函数使用filterwarnings过滤掉了
    import warnings
    
    def api_v1():
        warnings.warn(UserWarning("api v1, should use functions from v2"))
        return 1
    
    @pytest.mark.filterwarnings("ignore:api v1")
    def test_one():
        assert api_v1() == 1
    

    同样可以添加到pytestmark和pytest.ini中。

    • skip
      跳过,不测试。
      示例,skip需要添加reason
    @pytest.mark.skip(reason="no way of currently testing this")
    def test_the_unknown():
        ...
    

    不过,更实用的方式是调用pytest.skip(reason)函数,而不是用mark,这样就可以用if判断跳不跳

    def test_function():
        if not valid_config():
            pytest.skip("unsupported configuration")
    

    allow_module_level 可以跳过整个module

    import sys
    import pytest
    
    if not sys.platform.startswith("win"):
        pytest.skip("skipping windows-only tests", allow_module_level=True)
    
    • skipif
      if判断跳不跳,还可以用skipif。
      示例,如果Python版本小于3.6就跳过测试
    import sys
    
    @pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6 or higher")
    def test_function():
        ...
    

    如果想在summary中看到reason,需要添加-rs参数。
    可以把skipif赋值给变量,然后直接引用变量,或者把变量import到其他module中使用

    # content of test_mymodule.py
    import mymodule
    
    minversion = pytest.mark.skipif(
        mymodule.__versioninfo__ < (1, 1), reason="at least mymodule-1.1 required"
    )
    
    @minversion
    def test_function():
        ...
    
    # test_myothermodule.py
    from test_mymodule import minversion
    
    @minversion
    def test_anotherfunction():
        ...
    

    skipif添加到class上,会跳过类中所有方法。
    可以使用pytestmark跳过module内所有test

    # test_module.py
    pytestmark = pytest.mark.skipif(...)
    

    如果function有多个skipif作用,只要有一个为True,就会跳过。

    • xfail
      xfail就是expected fail,预期失败
    @pytest.mark.xfail
    def test_function():
        ...
    

    执行后summary不会统计为"failed",会单独列出来。如果结果失败了,“expected to fail” (XFAIL);如果结果成功了,“unexpectedly passing” (XPASS)。但是整个执行结果是”Tests passed“。
    if判断

    def test_function():
        if not valid_config():
            pytest.xfail("failing configuration (but should work)")
    

    值得注意的是,marker会继续执行所有test代码,pytest.xfail()函数会抛出异常,中断执行后续代码
    添加condition,判断条件

    @pytest.mark.xfail(sys.platform == "win32", reason="bug in a 3rd party library")
    def test_function():
        ...
    

    添加reason,理由

    @pytest.mark.xfail(reason="known parser issue")
    def test_function():
        ...
    

    添加raises,抛出异常/错误

    @pytest.mark.xfail(raises=RuntimeError)
    def test_function():
        ...
    

    添加run,禁止运行

    @pytest.mark.xfail(run=False)
    def test_function():
        ...
    

    添加strict,严格模式,即使xpass也会强制失败,summary中有输出信息”[XPASS(strict)] “,测试结果为”Tests failed“。

    @pytest.mark.xfail(strict=True)
    def test_function():
        ...
    

    断言成功也强制失败,确实够强势的!

    可以在ini文件中定义全局strict

    [pytest]
    xfail_strict=true
    

    在命令行添加--runxfail,忽略xfail marker,相当于没有添加这个标记的效果,该成功就成功,该失败就失败

    pytest --runxfail
    

    自定义marker

    通过注解自定义marker

    # content of test_server.py
    import pytest
    
    @pytest.mark.webtest
    def test_send_http():
        pass  # perform some webtest test for your app
    
    def test_something_quick():
        pass
    
    def test_another():
        pass
    
    class TestClass:
        def test_method(self):
            pass
    

    在命令行通过-m指定运行mark打标的test

    pytest -v -m webtest
    

    也可以反选

    pytest -v -m "not webtest"
    

    但是,这样定义的marker是未注册的!在执行后会警告,PytestUnknownMarkWarning。如果添加了命令行参数--strict-markers ,未注册的marker会报错。

    可以在pytest.ini文件中注册,冒号后面的所有代码都是marker说明,包括换行

    [pytest]
    markers =
        slow: marks tests as slow (deselect with '-m "not slow"')
        webtest:marks tests with webtest(deselect with '-m "not webtest"')
    

    更高级的,可以在pytest_configure hook函数中注册,这主要用在第三方插件

    def pytest_configure(config):
        config.addinivalue_line(
            "markers", "env(name): mark test to run only on named environment"
        )
    

    参考:
    https://www.cnblogs.com/df888/p/13715187.html
    https://www.osgeo.cn/pytest/example/markers.html
    https://docs.pytest.org/en/6.2.x/mark.html
    https://www.tutorialspoint.com/pytest/pytest_grouping_the_tests.htm
    https://www.numpyninja.com/post/registering-custom-markers-in-pytest

  • 相关阅读:
    Run Mac OS X on a PC
    asp:RadioButton javascript onclick event
    The SMTP server requires a secure connection or the client was not authenticated
    Mac OS could not mount diskXX with name after erase
    server does not support secure connections
    PETS 5 五级简介
    VB中的转义字符(回车、换行、Tab等)
    MAC (Mountain Lion)+Eclipse+python+Djgano+PyDve+MySQL 开发环境搭建
    Spring bean 实现生命周期的三种解决方案
    [APUE]第九章 进程关系
  • 原文地址:https://www.cnblogs.com/michaelcjl/p/15728309.html
Copyright © 2011-2022 走看看