pytest
*
– 一、安装及快速入门
–
+ 创建第一个测试用例
– 二、pytest的前后置
– 三、运行规则
–
+ 默认运行规则
+ 自定义运行规则
– 四、断言
– 五、
–
+ 标记mark的使用
+
* 标记
+ 跳过测试
– pytest参数化
–
+ 1.传入单个参数
+ 2.传入多个参数
– pytest常用的插件
– 项目案例应用
学习内容
- 介绍与快速入门
- 基本用法
- mark标记使用
- 参数化测试
- 常用插件
- 项目案例应用
特点:7
- 简答、已读
- 支持参数化
- 支持运行由unitest编写的测试Case
- 具有很多第三方插件,并且可以自定义扩展
- 支持重复执行失败的case
- 可以和持续集成工具集成
一、安装及快速入门
安装命令:pip3 install pytest
创建第一个测试用例
import pytest
def func(x):
return x+1
def test001():
print('-----test001用例-------')
assert func(3) == 6
def test002():
print('------test002用例--------')
assert func(3) == 4
if __name__ == '__main__':
pytest.main(["-vs","test_sample.py"])
二、pytest的前后置
(1)函数级别:setup、teardown
- 用于测试方法的始末
- 运行一次测试用例会运行一次setup和teardown
def test001():
print("teat001用例_类外")
def test002():
print("test002用例_类外")
def setup():
print('用例开始前执行')
def teardown():
print("用例后执行")
if __name__ == '__main__':
pytest.main(["-vs","test_method.py"])
运行结果:
(2)类级别:setup_class、teardown_class
- 运行于测试类的始末
(3)类中方法级别
- setup_method 、teardown_method
(4)模块级别(需放置类外):setup_module 、teardoen_module
- 所有模块开始始末
import pytest
def setup_module(self):
print("模块开始前运行")
def teardown_module(self):
print("模块结束后运行")
class Testclass():
def setup_class(self):
print("类开始前运行")
def teardown_class(self):
print("类结束后运行")
def setup_method(self):
print("类中方法开始前运行")
def teardown_method(self):
print("类中方法结束后运行")
def test001(self):
print("test001用例——类中")
def test002(self):
print("test002用例——类中")
def test003(self):
print("test003用例——类中")
if __name__ == '__main__':
pytest.main(["-vs","test_class.py"])
运行结果:
三、运行规则
默认运行规则
- 测试文件以test_ .py开头或以.test.py结尾
- 测试类以Test开头,并且不能带有__init__方法
- 测试函数以test_开头
自定义运行规则
文件名:pytest.ini(不可更改)
作用域:当前目录和其子目录下的所有case
[pytest]
addopts = -vs
testpaths=./testcase
python_files = test_*.py
python_classes = Test_* Test*
python_functions = test_* test*
运行结果:
四、断言
- 判断为真:assert XX
- 判断不为真:assert not XX
- 判断a包含b:assert a in b
- 判断a等于b:assert a==b
- 判断a不等于b:assert a != b
代码示例:
def fun(x):
x +=1
print(x)
return x
def test_true():
assert True
def test_false():
assert not True
def test_fun():
assert fun(2) == 3
def test_fun2():
assert fun(1) != 2
def test_a_in_b():
text = "jadkakhello,hfjbsv"
assert "hello" in text
运行结果:
testcase/test_assert.py::test_true PASSED
testcase/test_assert.py::test_false FAILED
testcase/test_assert.py::test_fun 3
PASSED
testcase/test_assert.py::test_fun2 2
FAILED
testcase/test_assert.py::test_a_in_b PASSED
五、
标记mark的使用
标记
@pytest.mark.标记名
def test_a(self):
pass
- 一个测试函数可以有多个标记
- 一个mark可以标记多个测试函数
- 运行参数pytest -m 标记名
- 运行多个参数pytest -m “标记名1 or 标记名2″(不运行添加not)
代码示例:
import pytest
class Test_mark():
@pytest.mark.ds001
@pytest.mark.ds002
def test_a(self):
pass
@pytest.mark.ds001
def test_b(self):
pass
@pytest.mark.ds0003
def test_c(self):
pass
命令行(多个用例同个标记场景):pytest -m ds001
运行结果:
(python3.9) (base) dongshuai@localhost ui-test % pytest -m ds001
====================================================================================== test session starts ======================================================================================
platform darwin -- Python 3.9.4, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /Users/dongshuai/venv/python3.9/bin/python
cachedir: .pytest_cache
rootdir: /Users/dongshuai/PycharmProjects/ui-test, configfile: pytest.ini, testpaths: ./testcase
plugins: variables-1.9.0
collected 3 items / 1 deselected / 2 selected
testcase/Test_mark.py::Test_mark::test_a PASSED
testcase/Test_mark.py::Test_mark::test_b PASSED
命令行(单个标记场景):pytest -m ds002
运行结果:
====================================================================================== test session starts ======================================================================================
platform darwin -- Python 3.9.4, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /Users/dongshuai/venv/python3.9/bin/python
cachedir: .pytest_cache
rootdir: /Users/dongshuai/PycharmProjects/ui-test, configfile: pytest.ini, testpaths: ./testcase
plugins: variables-1.9.0
collected 3 items / 2 deselected / 1 selected
testcase/Test_mark.py::Test_mark::test_a PASSED
命令行(多标记场景):pytest -m “ds002 or ds003”
运行结果:
====================================================================================== test session starts ======================================================================================
platform darwin -- Python 3.9.4, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /Users/dongshuai/venv/python3.9/bin/python
cachedir: .pytest_cache
rootdir: /Users/dongshuai/PycharmProjects/ui-test, configfile: pytest.ini, testpaths: ./testcase
plugins: variables-1.9.0
collected 3 items / 1 deselected / 2 selected
testcase/Test_mark.py::Test_mark::test_a PASSED
testcase/Test_mark.py::Test_mark::test_c PASSED
命令行(not场景):pytest -m “not ds001”
运行结果:
====================================================================================== test session starts ======================================================================================
platform darwin -- Python 3.9.4, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /Users/dongshuai/venv/python3.9/bin/python
cachedir: .pytest_cache
rootdir: /Users/dongshuai/PycharmProjects/ui-test, configfile: pytest.ini, testpaths: ./testcase
plugins: variables-1.9.0
collected 3 items / 2 deselected / 1 selected
testcase/Test_mark.py::Test_mark::test_c PASSED
跳过测试
- skip
标记skip表示跳过该测试用例运行不执行;
skip(reason=None) - skipif
条件判断验证是否忽略不执行
表达式:skipif(condition,reason=None)
@pytest.mark.skip在方法上:
import pytest
class Test_skip():
@pytest.mark.skip
def test_a(self):
pass
def test_b(self):
pass
运行结果:
testcase/Test_skip.py::Test_skip::test_a SKIPPED (unconditional skip)
testcase/Test_skip.py::Test_skip::test_b PASSED
@pytest.mark.skip在类上:
import pytest
@pytest.mark.skip
class Test_skip():
def test_a(self):
pass
def test_b(self):
pass
运行结果:
testcase/Test_skip.py::Test_skip::test_a SKIPPED (unconditional skip)
testcase/Test_skip.py::Test_skip::test_b SKIPPED (unconditional skip)
@pytest.mark.skipif(cndition,reason=None)
import pytest
age = 17
class Test_skip():
@pytest.mark.skipif(age<18,reason="年龄小于18不运行")
def test_a(self):
pass
def test_b(self):
pass
运行结果:
testcase/Test_skip.py::Test_skip::test_a SKIPPED (年龄小于18不运行)
testcase/Test_skip.py::Test_skip::test_b PASSED
pytest参数化
1.传入单个参数
@pytest.mark.parametrize(argnames,argvalues)
- argnames:参数名
- argvalues:参数对应值,类型必须为可迭代的类型,一般为list
代码示例:
import pytest
class Test_parametrize():
@pytest.mark.parametrize("name",["小董","小白","小黑"])
def test_a(self,name):
print(name)
运行结果:
testcase/Test_parametrize.py::Test_parametrize::test_a[\u5c0f\u8463] 小董
PASSED
testcase/Test_parametrize.py::Test_parametrize::test_a[\u5c0f\u767d] 小白
PASSED
testcase/Test_parametrize.py::Test_parametrize::test_a[\u5c0f\u9ed1] 小黑
PASSED
2.传入多个参数
@pytest.mark.parametrize((name,password),[(“xiaoxing”,”0000000″),(“xiaohong”,”111111″)])
list的每个元素都是一个元组,元组里的元素和参数里的顺序一一对应
代码示例:
@pytest.mark.parametrize("username,password",[("小董","000000"),("小白","111111"),("小黑","222222")])
def test_b(self,username,password):
print(username,password)
运行结果:
testcase/Test_parametrize.py::Test_parametrize::test_b[\u5c0f\u8463-000000] 小董 000000
PASSED
testcase/Test_parametrize.py::Test_parametrize::test_b[\u5c0f\u767d-111111] 小白 111111
PASSED
testcase/Test_parametrize.py::Test_parametrize::test_b[\u5c0f\u9ed1-222222] 小黑 222222
PASSED
pytest常用的插件
- 测试报告
安装:pip install pytest-html
使用:在配置文件中的命令行参数添加 –html=用户路径/repotr.html
- 失败重试
安装:pip install pytest-rerunfailres
使用:
1.在配置文件命令行参数中添加–reruns n
2.出错重试的等待时间,–reruns-delay
代码示例:
失败重试2次,且失败后延时3秒
pytest.ini配置:
[pytest]
addopts = -vs --html=./testcase/report.html --reruns 2 --reruns-delay 3
testpaths=./testcase
python_files = Test_*.py
python_classes = Test_* Test*
python_functions = test_* test*
用例:
import pytest
class Test_rerun_fail():
def test_a(self):
assert False
def test_b(self):
pass
运行结果:
testcase/Test_rerun_fail.py::Test_rerun_fail::test_a RERUN
testcase/Test_rerun_fail.py::Test_rerun_fail::test_a RERUN
testcase/Test_rerun_fail.py::Test_rerun_fail::test_a FAILED
testcase/Test_rerun_fail.py::Test_rerun_fail::test_b PASSED
项目案例应用
应用接口测试:使用pytest+resquests编写接口测试用例代码
实现步骤:
- 添加断言
- 参数化设置
- 插件应用
- 冒烟测试(分类执行)
- 按需求跳过用例
Original: https://blog.csdn.net/qq_44663072/article/details/115624460
Author: 董林夕
Title: pytest快速入门
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/776054/
转载文章受原作者版权保护。转载请注明原作者出处!