美文网首页
Pytest笔记

Pytest笔记

作者: 勇者与王者 | 来源:发表于2020-03-06 11:37 被阅读0次

    从年底换工作就没怎么写学习笔记了,期间在公司边学边用了 Android Python 过年在家看了iOS,还是b站神奇,竟然还有黑马的全套iOS视频,很nice ,就算纯小白应该也能看懂了,然后是最近老大要看pytest框架,国内查到的资料真不多,基本都是国外stack或别的地方写的example,记一下笔记:

    Pytest

    常用命令:
    pytest --collect-only 只收集用例不执行测试

    Pytest收集testcase

    默认查找以test_开头和_test结尾的.py文件
    从这些文件中查找以test开头的方法,包括 Test开头的类中的test* 方法
    识别以test.开头的所有方法、类

    Pytest fixtures

    1.用作不同 testcase之间共享数据
    在文件夹中创建conftest.py 将 fixture方法放在conftest中 则该文件夹下所有的testcase都可以使用该fixture
    2.实现unittest等框架类似的 setUp tearDown()方法
    通过在 [pytest.fixture]中指定 scope 参数来设置:@pytest.fixture(scope="module")

    • function —— 函数级,即调用每个测试函数前,均会重新生成 fixture
    • class —— 类级,调用每个测试类前,均会重新生成 fixture
    • module —— 模块级,载入每个测试模块前,均会重新生成 fixture
    • package —— 包级,载入每个包前,均会重新生成 fixture
    • session —— 会话级,运行所有用例前,只生成一次 fixture
    import pytest
    import smtplib
    
    @pytest.fixture(scope="module")
    def smtp_connection():
        return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
    

    yield smtp_connection 及前面的语句相当于测试前置,通过 yield 返回准备好的测试资源 smtp_connection; 而后面的语句则会在用例执行结束(确切的说是测试夹具的生效级别的声明周期结束时)后执行,相当于测试清理

    Pytest 用例执行顺序

    Pytest mark

    skip:
    skips a test unconditionally.
    无条件跳过一个用例

    skipif:
    skips a test if the expression passed to it evaluates to True.
    如果判断条件为真 则跳过

    xfail:
    indicates that a test is expected to fail, so if the test does fail, the overall suite can still result in a passing status.
    显式的声明一个用例会失败,如果确实失败,则测试结果显示为通过

    parametrize:
    (note the spelling) creates multiple variants of a test with different values as arguments.
    创建多个变量组为参数

    Pytest 参数化

    参数换成 pytest.param,我们还可以有更高阶的玩法,比如知道最后一组参数是失败的,所以将它标记为 xfail:

    @pytest.mark.parametrize(
        "test_input,expected",
        [("3+5", 8), ("2+4", 6), pytest.param("6*9", 42, marks=pytest.mark.xfail)],
    )
    def test_eval(test_input, expected):
        assert eval(test_input) == expected
    
    

    下面的示例中会分别把 x=0/y=2、x=1/y=2、x=0/y=3和x=1/y=3带入测试函数,视作四个测试用例来执行。

    如果测试函数的多个参数的值希望互相排列组合,我们可以这么写:@pytest.mark.parametrize("x", [0, 1])
    @pytest.mark.parametrize("y", [2, 3])
    def test_foo(x, y):
        pass复制代码上述示例中会分别把 x=0/y=2、x=1/y=2、x=0/y=3和x=1/y=3带入测试函数,视作四个测试用例来执行。
    
    

    参数化例子3:

    testdata = [
        (datetime(2001, 12, 12), datetime(2001, 12, 11), timedelta(1)),
        (datetime(2001, 12, 11), datetime(2001, 12, 12), timedelta(-1)),
    ]
    ​
    ​
    @pytest.mark.parametrize("a,b,expected", testdata)
    def test_timedistance_v0(a, b, expected):
        diff = a - b
        assert diff == expected
    

    Pytest 其他

    Test class中 test开头的case如果有参数,怎么避免自动附带self参数的问题
    pytest --durations=3 用来获取耗时最慢的3 个 testcase

    with pytest.raises(TypeError):
    ...
    预期pytest 抛出指定异常

    pytest 使用 . 标识测试成功(PASSED)

    pytest 使用 s 表示测试被跳过(SKIPPED)

    pytest 使用 F 标识测试失败(FAILED)

    pytest 使用 x 表示预见的失败(XFAIL)

    如果预见的是失败,但实际运行测试却成功通过,pytest 使用 X 进行标记(XPASS)

    可以使用 -v 选项,显示测试的详细信息

    第一种,显式指定函数名,通过 :: 标记。

    $ pytest tests/test-function/test_no_mark.py::test_func1

    第二种,使用模糊匹配,使用 -k 选项标识。

    pytest -k func1 tests/test-function/test_no_mark.py

    第三种,使用 pytest.mark 在函数上进行标记。

    带标记的测试函数如:

    @pytest.mark.finished
    
    def test_func1():
    
        assert 1 == 1
    
    @pytest.mark.unfinished
    
    def test_func2():
    
        assert** 1 != 1
    
    测试时使用 -m 选择标记的测试函数:
    

    $ pytest -m finished tests/test-function/test_with_mark.py

    跳过测试:@pytest.mark.skip(reason='out-of-date api')

    参数化:

    每组参数都独立执行一次测试。使用的工具就是 pytest.mark.parametrize(argnames, argvalues)

    # test_parametrize.py

    @pytest.mark.parametrize('passwd',

    ['123456',

    'abcdefdfs',

    'as52345fasdf4'])

    def test_passwd_length(passwd):

    assert len(passwd) >= 8

    @allure.step(“登陆”)

    Fixture是一些函数,pytest 会在执行测试函数之前(或之后)加载运行它们。

    可以将数据库连接 或测试环境准备初始化等操作 放在 fixture 中

    该测试函数执行完毕也会执行一遍 fixture

    二者用 yield 关键字进行分隔,即

    Fixture 标记函数yield之前的内容 在 测试函数之前运行 即。Setup

    。。。。。。。。。。之后的内容 在之后运行, 即 Teardown

    @pytest.fixture()

    def some_data():

    return 42

    def test_some_data(some_data): //将 fixture标记 的 函数作为 测试函数 testxx 的参数

    assert some_data == 42

    如果测试函数的参数列表中包含fixture修饰的函数名字,那么pytest能检测到,先搜索该测试所在的模块,再去。conftest.py 中搜索

    pytest --alluredir=/Users/tf/Desktop/PycharmProject/Pytest/Demo/Report

    Purest -s 参数 可以在命令行显示 print 语句的输出

    conftest.py

    import pytest
    @pytest.hookimpl(hookwrapper=True)
    def pytest_runtest_makereport(item, call):
    pytest_html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()
    extra = getattr(report, 'extra', [])
    if report.when == 'call':

    always add url to report

    extra.append(pytest_html.extras.url('http://www.example.com/')))
    xfail = hasattr(report, 'wasxfail')
    if (report.skipped and xfail) or (report.failed and not xfail):

    only add additional html on failure

    extra.append(pytest_html.extras.html('

    Additional HTML'))

    report.extra = extra

    string[::-1] 字符串切片

    相关文章

      网友评论

          本文标题:Pytest笔记

          本文链接:https://www.haomeiwen.com/subject/ogavrhtx.html