pytest安装
pip install pytest
pytest --version
官方文档: pytest中文文档
pytest测试发现规则
1、在执行入口pytest.main() 中没有指定任何参数 -> 会读取pytest.ini配置
2、找到上述指定的目录下的test_*.py 或 *_test.py文件
3、收集类Test*, 方法test_*
pytest.ini配置项
testpaths : 指定执行路径/目录
testpaths: webtestcases doc -> webtestcases、doc 目录下的所有test_文件都会被执行
norecursedirs : 指定不执行路径/目录
norecursedirs: webtestcases -> webtestcases目录下的test_文件不会被执行
python_classes: 指定执行哪些类
[pytest]
python_classes = *Suite
markers: 自定义标识,当 --strict-markers
或 --strict
使用命令行参数时,只执行使用已知标记
[pytest]
addopts = --strict-markers
markers = slow serial
python_files: 指定执行哪些文件
[pytest]
python_files = test_*.py check_*.py example_*.py
required_plugins: 必须存在才能运行pytest的插件的空格分隔列表。插件可以直接在其名称后面列出,
也可以不带版本说明符。不同版本说明符之间不允许有空格。如果没有找到任何一个插件,发出一个错误
[pytest]
required_plugins = pytest-django>=3.0.0,<4.0.0 pytest-html pytest-xdist>=1.0.0
usefixtures: 将应用于所有测试函数的设备列表;这在语义上与应用@pytest.mark.usefixtures 标记所有测试功能
[pytest]
usefixtures = clean_db
testpaths: 当所有项目测试都在一个已知的位置时很有用,以加速测试收集并避免意外地获取不需要的测试
[pytest]
testpaths = testing doc
addopts: 添加指定的 OPTS
命令行参数集,就好像它们是由用户指定的一样
[pytest]
addopts = --maxfail=2 -rf # exit after 2 failures, report fail info
pytest运行参数
-s: 打印信息
-v: 详细信息
-k: 运行指定包含某个字符串的测试函数
pytest.main(["-k","hello"]) -> 执行测试函数名中带有hello字符串的用例 (同样也可以指定类名,会执行类中所有测试方法)
pytest.main(["-k","类名 and not 方法名"])
-q: 简化输出
-x: 只要出现一条失败的用例都会退出
--maxfail: 用例失败个数达到阀值停止运行
pytest.main(["--maxfail=2"]) -> 超过2条运行失败,后续用例就会停止运行
-m: 指定带有标识的用例
pytest.main(["-m","smoke"]) -> 执行有 @pytest.mark.smoke 这个标记的测试用例
--durations: 查看最慢的n个用例
pytest.main(["--durations=10"]) 查看最慢10个用例
-p no:doctest 关闭插件,比如关闭doctest
pytest断言
语法:assert expression, errorMsg
assert a % 2 == 0, "value was odd, should be even"
预期异常的断言 pytest.raise() 递归超时
pytest参数化
1、@pytest.mark.parametrize(" 变量名... ", 数据)
2、metafunc.parametrize()
1 def pytest_generate_tests(metafunc):
2 idlist = []
3 argvalues = []
4 # metafunc.cls就是Test_Case类
5 for scenario in metafunc.cls.scenarios:
6 idlist.append(scenario[0])
7 items = scenario[1].items()
8 argnames = [x[0] for x in items] #
9 argvalues.append([x[1] for x in items])
10 # 给metafunc也就是Test_Case类下的方法全部带上这个parametrize
11 metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class")
12
13
14 scenario1 = ("basic", {"attribute": "value"})
15 scenario2 = ("advanced", {"attribute": "value2"})
16
17
18 class Test_Case:
19 scenarios = [scenario1, scenario2]
20
21 def test_demo1(self, attribute):
22 assert isinstance(attribute, str)
23
24 def test_demo2(self, attribute):
25 assert isinstance(attribute, str)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
testcases/test_case01.py::Test_Case::test_demo1[basic] PASSED
testcases/test_case01.py::Test_Case::test_demo2[basic] PASSED
testcases/test_case01.py::Test_Case::test_demo1[advanced] PASSED
testcases/test_case01.py::Test_Case::test_demo2[advanced] PASSED
3、@pytest.mark.parametrize(" 方法名", 数据, indirect=True) 将数据先传递给“方法名”对应的夹具函数进行处理,并且夹具函数接收一个参数request
1 @pytest.fixture
2 def fixt(request): # 这里需要带有参数request,request.param可以拿到["a", "b"]
3 return request.param * 3
4
5 @pytest.mark.parametrize("fixt", ["a", "b"], indirect=True) #indirect=True,会将数据["a", "b"]传递给fixt函数进行处理
6 def test_indirect(fixt):
7 assert len(fixt) == 3
pytest 生成测试报告
allure报告
1、安装jdk1.8才可以运行
2、解压Allure压缩包
3、配置Allure到环境变量 将allure下的bin配置到环境变量path中
生成allure报告: allure generate ./result/ -o ./report/ --clean
pytest.main(["--alluredir", "./result"])
pytest traceback输出 作为了解即可 就是显示报错信息的详细程度不同
pytest --showlocals
pytest -l
pytest --tb=auto 默认这种
pytest --tb==line .....
pytest pdb调试模式
pytest --pdb # 每次遇到失败都会进到调试 pdb
pytest -x --pdb # 第一次遇到失败进入pdb,结束测试执行
pytest --pdb --maxfail=3 # 只有钱三次失败跳转到pdb
进入pdb 交互调试常用命令
1、p : 输出变量expr的值
2、l : 列出错误,显示出错的代码
3、a : 打印当前函数的所有参数和变量
4、u : 移动到堆栈的上一层
5、d: 移动到堆栈的下一层
6、q : 退出pdb
pytest fixture夹具
1、@pytest.mark.usefixtures(xxx)
1、fixture函数没法传递返回值给测试用例
2、叠加使用usefixtures 叠加执行顺序 -> 先执行放下方,后执行放上方
2、fixture
autouse = True 测试用例自动使用该fixture函数
scope 指定作用域
params 指定传入的数据
案例演示 用于做数据驱动前 做数据处理
pytest 跳过测试用例
-
无条件跳过模块中的所有测试:pytestmark = pytest.mark.skip("all tests still WIP")
-
根据某些条件跳过模块中的所有测试:pytestmark = pytest.mark.skipif(sys.platform == "win32",reason="tests for linux only")
-
如果缺少某些导入,则跳过模块中的所有测试:pexpect = pytest.importorskip("pexpect")
当使用参数化时,可以对单个测试实例应用诸如skip和xfail之类的标记
pytest 与 unittest 对比
unittest | pytest | |
用例编写规则 | 1、需继承类 unittest.TestCase 2、测试方法以 test_ 开头 |
1、文件名 test_ 开头或 _test 结尾 2、类 Test 开头 3、方法 test_ 开头 |
用例分类执行 | 1、默认执行全部 2、使用suite 套件收集用例,执行部分用例 |
1、使用main配合参数执行 2、@pytest.mark 来标记执行部分用例 |
用例前置、后置 | 1、setUp、tearDown | 1、@pytest.fixture,更加灵活,结合conftest |
参数化 | 1、依赖ddt库 | 1、@pytest.mark.parametrize 装饰器 |
断言 | 1、assertEqual、assertIn、assertTrue、 assertFalse |
1、只有assert一个表达式 |
失败重跑 | 无 | 1、pytest-rerunfailuires插件 |
2023最新pytest自动化测试框架(全程干货),从0到1手把手教你搭建