pytest
pytest-html #生成htm格式的目动化测试报告
pytest-xdist #测试用例分布式执行。多CPU分发
pytest-ordering #用于改变测试用例的执行顺序
pytest-rerunfailures #用例失败后重跑
allure-pytest #用于生成美观的测试报告
放到 requirements.txt中,通过 pip install -r requirements.txt
allure下安装参考:安装方法
安装好后安装allure-pytest插件
主数榎式
(1)运行所有: pytest.main()
(2)指定模块: pytest.main("-vs’, test_login.py])
(3)指定目录: pytest. main(’-vs’, ’ /interface_ testcase)
(4)通过 nodeid指定用例运行: nodeid由模块名,分隔行,类名,方法名,数名组成
pytest. main(’-vs’, / interface_testcase/test interface py. 04 func))
pytest main(’-vs’ /interface_testcase/test interface::pytestintertace_03_zhiliao)
命令行榎式
(1)运行所有: pytest
(2)指定模块: pytest- vs test_login. py
(3)指定目录: pytest- vs /interface_ testcase
(4)指定目录: pytest- vs / interface_ testcase/test_interface. py::test_04_func
参数详解
-S:表示输出试信息,包括 print打印的信思
v:显示更细的信息
-vs:这两个参数数一起用
-n:支持多线程或分布式运行测试用例。
如: pytest -vs /testcase/test_login.py -n 2
reruns NUM:失败用例重跑
X:表示只要要一个用例服错,那么测试停止
-maxair=2 出现两个用例失败就停止
k:根据测试用例的部分字符串指定测试用例。
如: pytest -vs/ testcase- K "ao”
–html ./report/report.html :生成HTML的报告
[pytest]
addopts = -vs --html ./report/report.html #命令行的参数,用空格分隔
testpaths = ./testcase #测试用例的路径
python_files= test_*.py #模块名的规则
python_classes= Test* #类名的规则
python_functions= test* #方法名的规则
unittest :asclla的大小来绝对的执行的顺序
pytest:默认从上到下
改变默认的执行顺序:使用mark标记
@pytest.mark.run(order=3) 数值代表优先级,由1开始
smoke:冒烟用例,分布在各个模块里面
pytest -m “smoke”
pytest -m “smoke or usermanage or productmanage”
@pytest.mark.skip(reason='测试') #reason 写跳过的原因
@pytest.mark.skipif(age>=18,reason='已成年')
import pytest
class Test_login:
#在每个用例之前执行一次
def setup(self):
print('在执行用例之前的初始化代码:打开浏览器')
#在所有的用例之前只执行一次
def setup_class(self):
print('在每个类执行前的初始化工作:比如创建日志对象,创建数据库连接,创建接口的请求对象')
def teardown(self):
print('在执行测试用例后的执行:比如关闭浏览器')
def teardown_class(self):
print('在每个类执行后执行:比如销毁日志对象,关闭数据库连接')
@pytest.mark.run(order=3)
@pytest.mark.smoke
def test_1(self):
print('测试')
@pytest.mark.run(order=1)
@pytest.mark.usermanage
def test_2(self):
print('测试')
@pytest.mark.skip
def test_3(self):
print('测试')
def test_4(self):
print('测试')
if __name__ == "__main__":
pytest.main(['-vs','./','--reruns=2']) #--reruns=2 表示失败的地方重跑两次
#####scope的使用
import pytest
@pytest.fixture(scope='function')
def my_fixture():
print('这是前置的方法')
yield
print('这是后置的方法')
class Test_one:
def test_01(self):
print('01')
def test_02(self,my_fixture):
print('02')
if __name__ == '__main__':
pytest.main(['-vs','./test_01.py'])
================运行结果=======================
test_01.py::Test_one::test_01 01
PASSED
test_01.py::Test_one::test_02 这是前后置方法
02
PASSED
============================== 2 passed in 0.02s ==============================
####params的使用
import pytest
@pytest.fixture(scope='function',params=['test1','test2','test3'])
def my_fixture(request): #使用request 固定写法
print('这是前置的方法')
yield
print('这是后置的方法')
return request.param #param此时没有s
class Test_one:
def test_01(self):
print('01')
def test_02(self,my_fixture):
print('02')
print('------------'+str(my_fixture))
if __name__ == '__main__':
pytest.main(['-vs','./test_01.py'])
==========================打印结果=======================
test_01.py::Test_one::test_01 01
PASSED
test_01.py::Test_one::test_02[test1] 这是前置的方法
02
------------None
PASSED这是后置的方法
test_01.py::Test_one::test_02[test2] 这是前置的方法
02
------------None
PASSED这是后置的方法
test_01.py::Test_one::test_02[test3] 这是前置的方法
02
------------None
PASSED这是后置的方法
============================== 4 passed in 0.03s ==============================
总结
setup/teardown, setup_ class/teardown_class它是作用于所有用例或者所有的类
@ pytest.fixtrue() 它的作用是既可以部分也可以全部前后
contest.py和@pytest.fixtrue()结合使用,作用于全局的前后置
#######test_one.py里面的代码
class Test_one:
def test_01(self,cc):
print('01')
def test_02(self):
print('02')
#############test_two.py里面代码
class Test_two:
def test_01(self):
print('01')
def test_02(self,cc):
print('02')
print("---------------------"+str(cc))
#########conftest.py里面的代码
import pytest
@pytest.fixture(scope='function',params=['cc'],name='cc')
def my_fixture(request): #使用request 固定写法
print('这是前置的方法')
yield
print('这是后置的方法')
return request.param #param此时没有s
#############run里面的代码
import pytest
if __name__ == '__main__':
pytest.main(['-vs','./test_case/manage'])
#######################运行结果#################################
test_case/manage/test_01.py::Test_one::test_01[cc] 这是前置的方法
01
PASSED这是后置的方法
test_case/manage/test_01.py::Test_one::test_02 02
PASSED
test_case/manage/test_02.py::Test_two::test_01 01
PASSED
test_case/manage/test_02.py::Test_two::test_02[cc] 这是前置的方法
02
---------------------None
PASSED这是后置的方法
============================== 4 passed in 0.03s ==============================
assert
assert 1==2
下载,解压,配path路径
https://github.com/allure-framework/allure2/releases
path路径配置
验证: allure-- version
pycharm需要重启才能获取到
加入命令生成json格式的临时报告
–alluredir ./temp
生成 allure报告
os.system( ‘allure generate ./temp -o report -clean’)
allure generate 命令,固定的
./temp 临时的json格式报告的路径
-0 输出 output
/report 生成的 allure报告的路径
-clarn 清空 report路径原来的报吉
###############pytest.ini的代码
[pytest]
addopts = -vs --alluredir ./temp
testpaths = ./
python_files = test_*.py
python_classes = Test*
python_functions = test*
markers =
smoke:冒烟测试
usermanage:用户管理模块
###########run文件代码
import pytest
import os
if __name__ == '__main__':
pytest.main(['-vs','./test_case/manage'])
os.system('allure generate ./temp -o report --clean')
@pytest.mark.parametrize(args_name, args_value)
args_name:参数的名称
args_value:数的值 (list,tuple,字典列表,字典元组)
pytest默t认的测试用例的规则( pytest ini)
1、模块名必须以test或音是_test开头
2、类名必须以Test开头
3、方法名必须以test开头
import pytest
class Test_api:
#最基础的用法
@pytest.mark.parametrize('cc',['test1','test2','test3'])
def test_01(self,cc):
print(cc)
#解包的方法
@pytest.mark.parametrize('name,age',[['test1','18'],['test2','20'],['test3','21']])
def test_02(self,name,age):
print(name,age)
if __name__ == '__main__':
pytest.main(['-vs','./test.py'])
#####运行结果#################
test.py::Test_api::test_01[test1] test1
PASSED
test.py::Test_api::test_01[test2] test2
PASSED
test.py::Test_api::test_01[test3] test3
PASSED
test.py::Test_api::test_02[test1-18] test1 18
PASSED
test.py::Test_api::test_02[test2-20] test2 20
PASSED
test.py::Test_api::test_02[test3-21] test3 21
PASSED
============================== 6 passed in 0.04s ==============================
实例:
##################################yaml内容:
-
api_name: 获取网易新闻
api_request:
url: https://api.apiopen.top/getWangYiNews
method: post
headers:
Content-type: application/json
params:
page: 1
count: 5
api_valldate:
- eq: {code: 200,message: '成功'}
##################################读取yaml文件代码:
import yaml
def read_yaml(yaml_file):
"""
读取yaml文件
:return:
"""
with open(yaml_file,encoding='utf-8') as f:
data = yaml.load(f, Loader=yaml.FullLoader)
return data
##############################################用例:
import pytest
from Common.read_yaml import read_yaml
import requests
class Test_api:
@pytest.mark.parametrize('args',read_yaml('./case_01.yaml'))
def test_wy(self,args):
url = args['api_request']['url']
method = args['api_request']['method']
headers = args['api_request']['headers']
params = args['api_request']['params']
assertion = args['api_valldate']
if method == 'get':
res = requests.get(url)
else:
res = requests.post(url=url,json=params,headers=headers)
for i in assertion:
if i['eq']['code'] == res.json()['code'] and i['eq']['message'] == res.json()['message']:
print('测试成功')
if __name__ == '__main__':
pytest.main(['-vs','./test.py'])
使用方法 | 参数值 | 参数说明 |
---|---|---|
@alllure.epic() | epic描述 | 项目描述,往下是feature |
@allure.feature() | 模块名称 | 功能点的描述,往下是story |
@allure.story() | 用户故事 | 用户故事,往下是title |
@allure.title() | 用例的标题 | 重命名HTML报告的名称 |
@allure.testcase() | 测试用例的链接地址 | 对应测试用例系统里面的case |
@allure.issue() | 缺陷 | 对应缺陷管理系统里面的链接 |
@allure.description() | 用例描述 | 测试用例的描述 |
@allure.step() | 操作步骤 | 测试用例的步骤 |
@allure.severity() | 用例等级 | blocker、critical、normal、minor、trivial |
@allure.link() | 链接 | 定义一个链接,在测试报告展示 |
@allure.attachment() | 附件 | 报告添加附件 |