pytest 学习使用(一)

pytest测试发现规则

pytest将在当前目录及其子目录中运行所有格式为test _*.py* _test.py的文件,收集测试项目:

  • test 类之外的带前缀测试功能或方法
  • test前缀测试Test类中的前缀测试函数或方法(无__init__方法)

常用命令行参数

  • -vpytest -v,输出用例更加详细的执行信息,比如用例所在的文件及用例名称等

  • -rpytest -r在测试会话结束时显示“简短的测试摘要信息”,选项后接有多个字符,默认情况下列出fE:失败和错误

    选项后参数 例子 作用
    f pytest -rf 失败
    E pytest -rE 错误
    s pytest -rs 跳过
    x pytest -rx xfailed
    X pytest -rX xpass
    p pytest -rp 通过
    P pytest -rP 通过输出
    a pytest -ra pP的所有字符
    A pytest -rA 全部
    N pytest -rN 无,可用于不显示任何内容(fE默认设置)
  • -qpytest -q,输出用例简略的执行信息。

  • -mpytest -m name_of_mark,打印自定义标记测试。

    $ pytest -m slow		# 运行标记为slow的测试
    
  • -kpytest -k 'test_method or test_other',仅运行与给定字符串表达式匹配的测试,匹配字符串不区分大小写。

    $ pytest -k 'test_method or test_other'		# 匹配包含test_method或test_other的测试方法和测试类
    $ pytest -k 'not test_method'		# 匹配不包含test_method的测试方法和测试类
    $ pytest -k 'not test_method and not test_other' # 匹配不包含test_method和test_other的测试方法和测试类
    
  • -xpytest -x,遇到错误(第一个错误)立即停止测试。

  • --maxfail:`pytest --maxfail=N,遇到第N个错误立即停止测试。

    $ pytest -x			#在第一个失败后停止测试
    $ pytest --maxfail=2		#在第2个失败后停止测试
    
  • --durations=num -vvpytest --durations=num -vv,num为0时则倒序显示所有的用例,为具体值则显示耗时最长的对应该数量的用例,-vv 显示持续时间为0秒的用例,会按用例执行耗时时长:从长到短 显示结果,用于调优测试代码

    $ pytest --durations=3 -vv			# 要获取最慢的3个测试持续时间为0秒的列表
    ===================================== slowest 3 test durations =====================================
    0.00s call     test_example.py::test_fail
    0.00s setup    test_example.py::test_error
    0.00s setup    test_example.py::test_fail
    
  • --resultlogpytest --resultlog=path,生成普通的结果文件。

    $ pytest test_example.py --resultlog=./test.log		# 执行测试并在当前目录生成test.log结果文件(普通的结果文件)
    
  • --junitxmlpytest --junitxml=path,生成Junit结果文件,可被Jenkins其他持续集成服务器读取的结果文件。

    $ pytest test_example.py --junitxml=./report.xml	# 执行测试并在当前目录生成report.xml结果文件(Junit结果文件)
    

    --htmlpytest --html=path,生成html结果文件,可使用Jenkins的HTML插件读取展示。

    $  pytest test_example.py --html=./report.html	# 执行测试并在当前目录生成report.html结果文件(html结果文件)
    

断言

断言assert语句

pytest允许您使用标准python assert来验证Python测试中的期望和值。

Python assert(断言)用于判断一个表达式,**在表达式条件为 false 的时候触发断言异常。**断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况

语法格式assert expression,等价于:

if not expression:
    raise AssertionError

assert后面也可以紧跟参数:assert expression [, arguments],相当于:

if not expression:
    raise AssertionError(arguments)

预期异常的断言

  • 使用pytest.raises()触发期望断言
# 测试没有返回ValueError或者没有异常返回时,断言判断失败,否则断言成功
import pytest

def myfunc():
    raise ValueError("Exception 123 raised")

def test_match():
    with pytest.raises(ValueError):
        myfunc()			# 断言成功,pass

还可访问异常的属性,常用的属性包括:.type.value.traceback

import pytest

def myfunc():
    raise ValueError("Exception 123 raised")

def test_match():
    with pytest.raises(ValueError) as excinfo:
        myfunc()
    assert '123' in str(excinfo.value)
  • 使用pytest.mark.xfail()接收raises参数,来判断用例是否因为一个具体的异常而导致失败

如果f()触发一个IndexError异常,则用例标记为xfailed;如果没有,则正常执行f()

import pytest

def f():
    raise IndexError

@pytest.mark.xfail(raises=IndexError)
def test_f():
    f()

注意:

  • 如果f()测试成功,用例的结果是xpassed,而不是passed
  • pytest.raises适用于检查由代码故意引发的异常;而@pytest.mark.xfail()更适合用于记录一些未修复的Bug

函数标记功能pytest.mark

通过文件注册自定义标记

  • pytest.ini文件中注册自定义标记

    # content of pytest.ini
    [pytest]
    markers =
        标签1: 标签说明
        标签2: 标签说明
          ...
    
  • conftest.py注册自定义标记

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

使用@pytest.mark.name_of_the_mark装饰器注册自定义标记

使用@pytest.mark.name_of_the_mark装饰器上应用的未注册标记将始终发出警告,建议使用前两种方式

@pytest.mark.slow			# 注册slow的标记
def test_func():
		...

跳过用例 @pytest.mark.skip/@pytest.mark.skipif

  • @pytest.mark.skip

  • @pytest.mark.skipif

skipskipif可标记无法在某些平台上运行的测试功能,或希望失败的测试功能。要给跳过的测试添加理由和条件,应当使用skipif

标记函数参数化@pytest.mark.parametrize

可用于在测试用例方法前添加测试数据。

  • 传入单个参数,@pytest.mark.parametrize('参数名',lists)

  • 传入多个参数,@pytest.mark.parametrize(‘参数1’,‘参数2’,[(参数1_data[0],参数2_data[0]),参数1_data[1],参数2_data[1])]

    list的每个元素都是一个元祖,元祖里的每个元素和按参数顺序一一对应。

  1. 例:传入两个参数
import pytest
@pytest.mark.parametrize("test_input,expected",
                         [ ("3+5", 8),
                           ("2+4", 6),
                           ("6 * 9", 42),
                         ])
def test_eval(test_input, expected):
    assert eval(test_input) == expected
  1. 例:传入参数组合
import pytest
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
    print("测试数据组合:x->%s, y->%s" % (x, y))

输出:


test_example.py::test_foo[2-0] PASSED                                    [ 25%]测试数据组合:x->0, y->2
test_example.py::test_foo[2-1] PASSED                                    [ 50%]测试数据组合:x->1, y->2
test_example.py::test_foo[3-0] PASSED                                    [ 75%]测试数据组合:x->0, y->3
test_example.py::test_foo[3-1] PASSED                                    [100%]测试数据组合:x->1, y->3

测试准备与结束

setup-可用于测试准备

teardown-可用于测试结束的数据清理/环境重置等

用例运行级别

  • **模块级(setup_module/teardown_module)**开始于模块始末,全局的
  • **函数级(setup_function/teardown_function)**只对函数用例生效(不在类中)
  • **类级(setup_class/teardown_class)**只在类中前后运行一次(在类中)
  • **方法级(setup_method/teardown_method)**开始于方法始末(在类中)
  • **类里面的(setup/teardown)**运行在调用方法的前后

setup_methodteardown_method的功能和setup/teardown功能是一样的,一般二者用其中一个即可。

模块级

# 模块级准备与结束,setup_module()在测试模块前执行测试用例一次,teardown_module()在测试模块测试用例结束执行后一次
# content of test_one.py
import pytest
import sys

def setup_module():
    print("setup_module:整个.py模块只执行一次")

def teardown_module():
    print("teardown_module:整个.py模块只执行一次")

def setup_function():
    print("setup_function:每个用例开始前都会执行")

def teardown_function():
    print("teardown_function:每个用例结束后都会执行")

def test_one():
    print(f"正在执行----{sys._getframe(0).f_code.co_name}")
    x = "this"
    assert 'h' in x

def test_three():
    print(f"正在执行----{sys._getframe(0).f_code.co_name}")
    a = "hello"
    b = "hello world"
    assert a in b

if __name__ == "__main__":
    pytest.main(["-v"])

输出

============================= test session starts =============================
platform win32 -- Python 3.6.7rc1, pytest-6.0.1, py-1.9.0,</
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值