哈咯,大家,我们今天来学习pytest单元测试框架,这个框架要比unittest更加易于使用,结构性也更加好,希望大家能够从中学习到有用的东西,然后在下一章,我们来使用pytest单元测试框架来搭建一个web自动化测试项目,一起加油!
直接上整体学习项目结构图:pytest项目结构
pytest1.安装pytest:pip3 install pytest
2.pytest框架下的,测试文件和测试函数都要以test开头
3.在命令行输入,pytest,即会执行test开头的文件
4.pytest.main()也同样可以开始执行 - pytest会在当前命令行所在目录下全局搜索test开头的文件进行执行测试
这里我们主要针对unittest 和 pytest的不同之处进行学习
一、断言:
pytest并没有提供专门的断言方法,而是直接使用assert进行断言,如:
assert a == b
assert a in b
assert abc() is True
assert not abc()
assert abc() is False
二、Fixture:
是对测试方法、测试函数、测试类和整个测试文件进行初始化或还原测试环境
例:
# 装饰器从session -> module -> class -> function
(都是针对每个里面包含的用例去执行,覆盖单位是用例)
session:多个文件调用一次,可以跨.py文件调用,每个.py是一个module
module:每个.py文件调用一次,每个.py是一个module
class:每个类调用一次
function:每个函数或方法调用一次
# 如果你想一个module下的都用上,那就打开改成True, 如下,这样就不需要往每个函数里传入fixture
# yield xxx接着后续的代码实现tearDown的功能
# 如果是把fixture单独存放,定义一个conftest.py, 该文件要和case在同级目录下,case文件中声明# content of conftest.py
conftest.py:
# coding = utf8
import os
os.path.abspath(".")
from time import sleep
import pytest
"""
a py file which saved pytest's fixture for use
"""
@pytest.fixture(scope = "function")
def before_case_execute():
sleep(3)
yield before_case_execute
sleep(3)
test_sample.py:
# coding = utf8
# content of conftest.py
import os
os.path.abspath(".")
import pytest
from time import sleep
# 装饰器从session -> module -> class -> function
# 如果你想一个module下的都用上,那就打开改成True, 如下,这样就不需要往每个函数里传入fixture
# yield实现tearDown的功能
@pytest.fixture(scope = "function")
def before_each_case():
sleep(3)
print("Set up now")
yield before_each_case
sleep(3)
print("Tear down now")
def add(x):
return x + 1
# def test_add(before_each_case):
def test_add(before_case_execute):
assert add(3) == 4
if __name__ == "__main__":
pytest.main()三、参数化
pytest的参数化与unittest类似,通过@pytest.mark.parameterize进行装饰,传入需要的值名、值、以及为每一个值指定对应的case名
test_parameterize.py:
# coding = utf8
import os
os.path.abspath(".")
# pytest参数化
import pytest
@pytest.mark.parametrize(
"x, y, z",
[(1, 2, 9), (4, 5, 9), (7, 8, 5)],
ids = ["case1", "case2", "case3"]
)
def test_add(x, y, z):
assert x + y == z
# terminal进入当前py文件路径,pytest -v test_parameterize.py指定执行
# if __name__ == "__main__":
# pytest.main(["-v", "-k add", "./test_parameterize.py"])四、运行测试
1.指定名称中包含某字符串的用例执行:pytest -k add test_parameterize.py
2.减少运行的冗长日志信息:pytest -q test_parameterize.py
3.如果出现一条测试用例失败则退出测试:pytest -x test_parameterize.py
4.运行测试目录:pytest ./pytest_object
5.指定特定类或方法执行:pytest test_parameterize.py::test_add 用::进行分隔
6.通过main()运行测试:pytest.main(["-v", "-k add", "./test_parameterize.py"]) 每个参数用逗号隔开
五、生成测试报告
1.生成JUnit XML文件:pytest ./pytest_project --junit-xml=./pytest_project/report/pytest_log.xml
2.生成在线测试报告:pytest test_parameterize.py --pastebin=all 执行到最后会生成一个链接,如下:View paste B3CAbpaste.net
六、conftest配置文件
(conftest.py 是pytest特有到本地测试配置文件:
1.可以用来设置项目级别的Fixture
2.导入外部插件
3.指定钩子函数)
pytest扩展1.生成HTML格式的测试报告:
pip3 install pytest-html
pytest ./pytest_project --html=./pytest_project/report/pytest_html_result.html
2.在用例失败时重试:
pip3 install pytest-rerunfailures
pytest -v pytest_expand.py --reruns 3
(重试机制可以增加测试用例的稳定性,避免因为一些网络原因、机器卡顿导致的问题)
3.pytest-parallel扩展:
pip3 install pytest-parallel
pytest -q pytest_expand.py --tests-per-worker auto
(使用并行运行测试case测试可能会导致互相产生干扰,需要谨慎使用)
# coding = utf8
import os
os.path.abspath(".")
import pytest
"""
pytest扩展
"""
# pytest ./pytest_project --html=./pytest_project/report/pytest_html_result.html
def test_add():
assert 1 + 1 == 3
关注 + 收藏 + 点赞哦,谢谢啦~