pytest学习实践(二)
断言
pytest的断言就用的python最基本的assert
1 2 3 4 5 6 7 8 9 10
| import pytest
def func(x): return x + 1
def test_func(): assert func(3) == 5
if __name__ == '__main__': pytest.main(['-q'])
|
异常捕获
用raises来捕获预期的异常
1 2 3 4 5 6 7 8 9 10 11 12
| import json import pytest
def func(): filename = 'package.json' with open(filename) as f_obj: json.load(f_obj) raise FileNotFoundError
def test_func(): with pytest.raises(FileNotFoundError): func()
|
多个类组成用例
1 2 3 4 5 6 7 8 9 10 11 12 13
| import pytest
class TestClass(): def test_one(self): x = "this" assert 'h' in x
def test_two(self): x = 'hello' assert hasattr(x, 'check')
if __name__ == '__main__': pytest.main(['-q'])
|
只要函数以test_开头,都可以识别
指定测试case
1 2 3 4 5 6 7 8 9 10
| def test_one(): x = "this" assert 'h' in x
def test_two(): x = 'hello' assert hasattr(x, 'check')
if __name__ == '__main__': pytest.main(['-q', 'test_2.py::test_one'])
|
但是这样的方式只能指定一个函数,如果需要执行多个,就有点麻烦
使用pytest.mark
进行标记
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @pytest.mark.commit def test_one(): x = "this" assert 'h' in x
@pytest.mark.finished def test_two(): x = 'hello' assert hasattr(x, 'check')
@pytest.mark.finished def test_three(): assert 1 == 2
if __name__ == '__main__': pytest.main(['-m', 'finished']) # os.system('pytest -m finished')
|
使用mark进行标记,标记哪些需要执行,也支持:pytest -m "commit and finished"
跳过测试
1 2 3 4
| @pytest.mark.skip def test_two(): x = 'hello' assert hasattr(x, 'check')
|
也支持skipif
1 2 3
| @pytest.mark.skipif(sys.platform == "win32", reason="not support win32") def test_four(): assert 1 == 1
|
捕获遇见错误xfail
使用xfail来标记,期望该测试函数执行失败(执行失败,但又不想跳过);配合配置文件test.ini
,文件中指定标志位,例如:
1 2
| [pytest] xfail_strict=true
|
1 2 3 4 5
| @pytest.mark.xfail(strict=True) def test_five(): a = id(["1", "2", "3"]) b = id([1, 2, 3]) assert a == b
|
运行返回结果x
表示XFAIL
预见的失败;X
表示XPASS
预见的成果
也可以用pytest --runxfail
强制执行标记xfail的用例
参数化
pytest使用pytest.mark.parametrize(argnames, argvalues)
进行参数化实现
1 2 3
| @pytest.mark.parametrize('passwd', ['12345678909', 'sdsddewd']) def test_six(passwd): assert len(passwd) >= 10
|
测试结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| .F [100%] ================================== FAILURES =================================== _____________________________ test_six[sdsddewd] ______________________________
passwd = 'sdsddewd'
@pytest.mark.parametrize('passwd', ['12345678909', 'sdsddewd']) def test_six(passwd): > assert len(passwd) >= 10 E AssertionError: assert 8 >= 10 E + where 8 = len('sdsddewd')
test_2.py:31: AssertionError 1 failed, 1 passed in 0.15 seconds
|
case重试
安装插件
1
| pip install -U pytest-rerunfailures
|
执行
1 2 3
| if __name__ == '__main__': pytest.main(['-s', '-q', '--reruns', '3']) # os.system('pytest -s -q test_2.py --reruns 3')
|
1
| 1 failed, 1 warnings, 3 rerun in 0.13 seconds
|
可以指定单个case重试
多进程运行cases
安装插件
1
| pip install -U pytest-xdist
|
执行
1 2 3
| if __name__ == '__main__': # pytest.main(['-s', '-n', '3']) os.system('pytest -s -n 3 test_2.py')
|
1 2
| gw0 I / gw1 I / gw2 I gw0 [1] / gw1 [1] / gw2 [1]
|
生成测试报告(htmlReport)
安装插件
1
| pip install -U pytest-html
|
执行
1 2 3
| if __name__ == '__main__': # pytest.main(['--html=report.html']) os.system('pytest test_2.py --html=report.html')
|
报告很好看!