目录
1、概述
2、使用介绍
2.1、安装pytest
2.2、pytest编写规范
2.3、setup、teardown操作
2.4、断言
2.5、标记失败重跑次数
3.6、pytest-xdist 多CPU分发并行执行用例
3.7、使用装饰器@pytest.mark.usefixtures()修饰需要前运行的用例
3、数据驱动
3.1、单个参数
3.2、多个参数
3.3、使用多个@pytest.mark.parametrize()装饰器
3.4、运用文件数据作为参数
4、运行程序
4.1、单个程序运行
4.2、多个程序运行
4.3、批量运行
pytest是一个非常成熟的全功能的python测试框架,主要特点有一下:
pip install pytest
def setup(self):
print("用例执行前都会执行")
def teardown(self):
print("用例执行后都会执行")
@classmethod
def setup_class(self):
print("执行class前只会执行一次")
@classmethod
def teardown_class(self):
print("执行class后只会执行一次")
assert '100000' == res.json()['code'] # 断言使用Python原生assert
assert '注册成功' in res.json()['msg']
安装:pip3 install pytest-rerunfailures
命令:pytest --reruns 5 test_pytest.py
用命令运行或在代码中运用@pytest.mark.flaky
@pytest.mark.flaky(reruns=5, reruns_delay=1) # 如果失败则延迟1s后重跑
def test_user_reg() # 最多重跑5次, reruns_delay可以不传 ...
assert 1==2
安装:pip3 install pytest-xdist
#分2个进程跑,如果有6个方法,第一个进程固定跑1、3、5,第二个进程固定跑2、4、6
命令:pytest test_01.py -n 2
需要每个用例前执行标记方法,代码如下:
import pytest
@pytest.fixture() #标记
def test1():
print("\n------我是test1-----")
@pytest.mark.usefixtures("test1")
#运行每个用例前都会执行test1,括号里面是方法名,pytest.mark.usefixtures写在class前,功能与setup一致
class Testpytest():
def test_1(self):
print("我是1")
def test_2(self):
print("我是2")
运行结果:
------我是test1-----
我是1
------我是test1-----
我是2
只需要在指定用例前执行标记方法,代码如下:
import pytest
# @pytest.fixture()\
@pytest.fixture()
def test1():
print("\n------我是test1-----")
return 1234
class Testpytest():
@pytest.mark.usefixtures("test1")
def test_1(self):
print("我是1")
# print(test1)
def test_2(self):
print("我是2")
运行结果:
------我是test1-----
我是1
我是2
需要标记方法的return值时,只能通过方法名作为参数传入,代码如下:
import pytest
@pytest.fixture()
def test1():
print("\n------我是test1-----")
return 1234
class Testpytest():
def test_1(self, test1):
print("我是1")
print(test1)
运行结果:
------我是test1-----
我是1
1234
如果一个class需要调用多个fixture,可以使用多个@pytest.mark.usefixtures()修饰器,注意先执行的放下底层,后执行放在上层,代码如下:
import pytest
@pytest.fixture()
def test1():
print("\n------我是test1-----")
@pytest.fixture()
def test2():
print("\n------我是test2-----")
@pytest.mark.usefixtures("test2")
@pytest.mark.usefixtures("test1")
class Testpytest():
def test_1(self):
print("我是1")
运行结果:
------我是test1-----
------我是test2-----
我是1
数据驱动运用pytest.mark.parametrize()装饰器,把测试过程中需要的测试数据提取出来,传递参数的个数来决定程序运行的次数
在使用pytest.mark.parametrize()
传递参数化数据时,测试用例本身必须有参数。第一个参数为字符串格式,第二参数为数据,数据的个数决定用例运行的次数
import pytest
class Testpytest():
@pytest.mark.parametrize("a", ("1", "2", "3"))
# a作为装饰器传入值的变量,参数必须以元组或列表形式出现
def test_1(self, a): # 作为用例参数,接受装饰器传入的值
print("\na是:"+a)
运行结果:
a是:1
.
a是:2
.
a是:3
多个参数,第一个字符串,对应用例的多个参数,以逗号隔开;第二个参数为数据
import pytest
class Testpytest():
@pytest.mark.parametrize("a,b", [("1", "2"), ("3", "4"), ("5", "6")])
def test_1(self, a, b):
print("\na+b是:"+a+b)
运行结果:
a+b是:12
.
a+b是:34
.
a+b是:56
import pytest
class Testpytest():
@pytest.mark.parametrize("a", ("1","2"))
@pytest.mark.parametrize("b", ("4","5"))
def test_1(self, a, b):
print("\na+b是:"+a+b)
运行结果:
a+b是:14
.
a+b是:24
.
a+b是:15
.
a+b是:25
写一个读取文件数据,返回一个list数组的方法
import pytest
def data():
with open("C:/Users/Administrator/Desktop/香港大盘成分股.txt", encoding="utf8") as f:
datas = f.read().split("\n")
return datas
class Testpytest():
@pytest.mark.parametrize("a", data())
def test_1(self, a):
print("\n成分股:"+a)
在工程目录下新建runner.py文件,内容如下:
# coding:utf-8
import pytest
import os
# 文件路径 # 存入文件的路径
pytest.main(['./case/test_abc.py','-s', '--alluredir', './temp'])
运行多个程序,则增加多个pytest.main()
# coding:utf-8
import pytest
import os
pytest.main(['./case/test_login.py','-s', '--alluredir', './temp'])
pytest.main(['./case/test_abc.py','-s', '--alluredir', './temp'])
在该程序目录新建pytest.ini文件(名称不能改),pytest.ini内容如下:
-v:详细显示输出
case目录下的test_abc程序下Test_run类下的test_1方法,运行结果:PASSED
-s:显示print结果
显示:---a---
[pytest]
# 添加命令行参数
addopts = -v -s --alluredir ./temp
# 文件搜索路径
testpaths = ./case/
# 类名称
python_classes = Test*
# 方法名称
python_functions = test_*
# 文件名称
python_files = test_*.py
设置好pytest.ini文件后,运行命令:pytest