pytest学习实践(二)

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

报告很好看!

文章目录
  1. 断言
  2. 异常捕获
  3. 多个类组成用例
  4. 指定测试case
  5. 跳过测试
  6. 捕获遇见错误xfail
  7. 参数化
  8. case重试
  9. 多进程运行cases
  10. 生成测试报告(htmlReport)
|