文章目录
一、接口自动化之request
1.1 基础方法了解
- 请求方式:get,post,delete,put
- 请求参数类型:键值对,json格式,文件格式
import requests
rep = requests.request()
# 返回字符串的数据
print(rep.text)
# 返回字节格式的数据
print(rep.content)
# 返回字典格式的数据
print(rep.json())
# 状态码
print(rep.status_code)
# 返回状态信息
print(rep.reason)
# 返回cookie信息
print(rep.cookies)
# 返回编码格式
print(rep.encoding)
# 返回响应头信息
print(rep.headers)
1.2 案例的展示
- get请求通过params传递参数
- post通过json或data传参,
# 使用pytest框架进行测试
class TestSendRequest:
# 全局变量(通过类名访问)
access_token = ""
def test_get_token(self):
# 发送get请求 ctrl+鼠标左键可以查看方法参数解释
url = "https://api.weixin.qq.com.cgi-bin/token"
data = {
"grant_type": "client_credential",
"appid": "APPID",
"secret": "APPSECRET"
}
# def get(url, params=None, **kwargs)
rep = requests.get(url=url, params=data)
print(rep.json())
TestSendRequest.access_token = rep.json()['access_token']
def test_edit_flag(self):
# 发送post请求 (data和json只要传一个就可以了)
# def post(url, data=None, json=None, **kwargs):
url = "https://api.weixin.qq.com.cgi-bin/tags/update?access_token=" + TestSendRequest.access_token + ""
data = {"tags": {"id": 123, "name": "广东人"}}
rep = requests.post(url, json=data)
'''
json.dumps(data)序列化 把字典格式数据转换为str格式
json.loads(data)反序列化 把str格式转换成字典格式
'''
# 使用data传参,需要先转成字符串格式,直接传入字典格式,它是表单形式的,不可以
# rep = requests.post(url, data=json.dump(data))
print(rep.json())
def test_file_upload(self):
url = "https://api.weixin.qq.com.cgi-bin/tags/update?access_token=" + TestSendRequest.access_token + ""
data = {
"media":open(r"E:\shu.png",'rb')
}
# 文件上传使用files
rep = requests.post(url=url,files=data)
print(rep.json())
if __name__ == '__main__':
pytest.main(['-vs'])
post通过json或data传参,区别是什么?
-
总结
data只能传*简单的只有键值对(无嵌套)*的dict或者是str格式
json一般只能传dict格式(简单或者嵌套都可以)
数据报文类型 | 请求头 | |
---|---|---|
data | dict字典类型 | application/x-www-form-urlencoded 表示以form表单的方式传参,格式a=1&b=2 |
str类型 | text/plain (如果是字典类型需要转换成str格式传参) | |
json | 无论是dict还是str类型 | 默认都行application/json,格式: {“a”:1,“b”:2} |
- cookie鉴权: 网页的接口,基本都需要做cookie鉴权(不常用),可以通过session实现cookie鉴权(常用)
1.3 接口自动化测试框架封装
-
接口自动化框架封装的第一步,统一请求方法
无论是get还是post请求,都可以使用
request
方法,前面加
"get"/"post"
参数
# cookie鉴权: 网页的接口,基本都需要做cookie鉴权(不常用)
# 通过session实现cookie鉴权(常用)
rep = requests.request("post",url=url,data=data,headers=headers,cookies=TestSendRequest.cks)
-
session的获取
session表示一个对话
session = requests.session()
-
案例,在注释部分
post –> 使用request(“post”,…)
requests.request(…,cookies=xxx) –> 不使用cookies,使用session调用session.request(xxx)
# 请求需要带请求头的接口
def test_login(self):
url = "https://api.weixin/pwind"
data = {
"username":"hh",
"pwd":"pwd",
"secret":"secret",
"token":TestSendRequest.csrf_token.csrf_token
}
# 请求头
headers = {
"Accept":"application/json,text/javascript,/;q=0.01",
"X-Requested-With":"XMLHttpRequest"
}
# 简单键值对,可以直接data传参
# rep = requests.post(url=url,data=data,headers=headers,cookies=TestSendRequest.cks)
# rep = requests.request("post",url=url,data=data,headers=headers,cookies=TestSendRequest.cks)
rep = TestSendRequest.session.request("post",url=url,data=data,headers=headers)
print(rep.json())
二、pytest用例管理框架
-
pytest框架默认规则:
1.py文件必须以test_开头或者_test结尾
2.类名必须以Test开头
3.测试用例必须以test_开头 -
pytest框架作用
1.发现测试用例:从多个py文件中通过默认的规则去找测试用例
2.执行测试用例:顺序和条件
3.判断测试结果:断言
4.生成测试报告:html,allure
2.1 pytest 全局观
- 可以和所有的自动化测试工具selenium,requests,applium结合,实现web自动化,接口自动化以及app自动化
- 跳过用例以及失败用例重跑
- 结合allure生成美观的测试报告
- 和jenkins持续集成
-
有很多的强大插件
pytest-html 生成html测试报告
pytest-xdist 多线程运行
pytest-ordering 改变测试用例的执行顺序
pytest-rerunfailures 失败用例重跑
allure-pytest 生成allure测试报告
-
一次性安装插件
在根目录下,新建一个txt文档,列出要安装的插件,在terminal窗口中输入命令安装即可
pip install -r requirements.txt
# requirements.txt
pytest
pytest-html
pytest-xdist
pytest-ordering
pytest-rerunfailures
allure-pytest
2.2 运行方式
-
主函数的方式(命令行的方式)
-v 输出更加详细的运行信息
-s 输出调试信息
-n 多线程运行
–reruns 数字 失败用例重跑
–html 生成报告
if __name__ == '__main__':
pytest.main(['-vs','-n=2'])
- 遇到一个问题:不生成报告,可能是因为之前的代码运行报错,没有执行到语句
import pytest
class TestPao:
def test_get_token(self):
print("测试")
# if __name__ == '__main__':
pytest.main(['-vs','--html=./report.html'])
-
pip的升级
参考
-
实际工作中使用
pytest.ini
的配置文件来配置运行
[pytest]
addopts = -vs -m "smoke" //只运行smoke类的测试用例
testpaths = ./testcases //测试用例存放路径
python_files = test_*.py //规定文件名、类名、方法名格式
python_classes = Test*
python_functions = test_*
markers =
smoke:maoyan
import pytest
class TestSendRequest:
# 标记 -- 执行
@pytest.mark.smoke
def test_send(self):
print("one")
# 不执行
def test_other(self):
print("two")
if __name__ == '__main__':
pytest.main()
2.3 前后置、夹具
-
前后置的方法/类
setup/teardown 在每个用例之前和之后执行一次
setup_class/teardown_class 在每个类之前和之后执行一次
def setup(self):
print("每个用例前执行")
def teardown(self):
print("每个用例后执行")
-
部分前置
@pytest.fixture
(scope=“作用域”,params=“数据驱动”,autouse=“自动执行”,ids=“自定义参数”,name=“重命名”)
作用域:function,class,module,package/session
@pytest.fixture(scope="function")
def conn_database():
print("连接数据库")
yield
print("关闭数据库")
class TestSendRequest:
...
# 直接将方法名作为参数传入
def test_other(self,conn_database):
print("two")
...
- 一般情况下,不会使用上面的写法,@pytest.fixture会和conftest.py文件一起使用
-
conftest.py名称是固定的,功能很强大
conftest.py文件是单独存放@pytest.fixture方法的,用处是可以在多个py文件之间共享前置配置
conftest.py里面的方法在调用时不需要导入,可以直接使用
conftest.py可以有多个,也可以有多个不同的层级
2.4 接口自动化测试框架封装(接口关联的封装)
一般情况下,我们是通过一个关联的yaml文件来实现
以下为实操演示:
- 在项目的根目录下新建一个extract.yml文件
- 新建一个python文档,用来存放一些公共的操作,例如yaml文件的工具类
import os
import yaml
class YamlUtil:
# 读取extract.yml文件
def read_extract_yaml(self,key):
with open(os.getcwd()+"/extract.yml",mode='r',encoding='utf-8') as f:
value = yaml.load(stream=f,Loader=yaml.FullLoader)
return value[key];
# 使用追加的方式写 a
# 写入extract.yml文件
def write_extract_yaml(self,data):
with open(os.getcwd()+"/extract.yml",mode='a',encoding='utf-8') as f:
value = yaml.dump(data=data,stream=f,allow_unicode=True)
# 清除extract.yml文件
def clear_extract_yaml(self):
with open(os.getcwd()+"/extract.yml",mode='w',encoding='utf-8') as f:
f.truncate()
- 测试用例经常需要调用的值,例如token,鉴权码,不要以全局变量的方式展示,而是存储到yml文件中,这样在多个py文件中也可以获取
# 测试yaml
def test_getValue(self):
print('直接写入yaml')
YamlUtil().write_extract_yaml({'access_token':'test_token'})
def test_readValue(self):
print('读取yaml')
value = YamlUtil().read_extract_yaml('access_token')
print(value)
运行程序后得到:
- 这里有一个问题,就是多次运行程序,会得到多个相同的键值,也就是yaml文件中有重复项,那么就需要进行清除(可以看到上面yaml工具类中的清除方法)
- 我们可以利用@pytest.fixture会和conftest.py来实现,每次会话之后做一次清除,就可以写入新的值了
# conftest.py
# 自动执行,并且一次会话就会触发
@pytest.fixture(scope="session",autouse=True)
def clear_yaml():
YamlUtil().clear_extract_yaml()
- python 接口断言
# 断言
assert 'url' in 'access_token' and 1==1
断言不成立时会报错:
2.5 python 结合allure-pytest生成allure测试报告
-
官网下载allure: https://github.com/allure-framework/allure2/releases
放在没有中文的目录下,并把allure的bin目录配置到环境变量的path中 -
重启pycharm
在命令行窗口通过allure –version验证 (无效可以重启电脑) -
执行命令
(1)生成临时的json文件的命令
--alluredir ./temp
(2)通过临时的json文件生成allure报告 os.system()
三、接口自动化测试框架YAML数据驱动的封装
@pytest.mark.parametrize(args_name,args_value)
args_name: 参数名
args_value:参数值(使用list列表,tuple元组,字典列表,字典元组等)
在数据中有多少个值,那么接口用例就会执行多少次
import pytest
class TestApi:
# 基础用法
# 三个value执行三次
@pytest.mark.parametrize('args',['百丽','杏眼','依然'])
def test_api1(self,args): # 传参名称一致 args
print("百丽")
# 解包
@pytest.mark.parametrize('name,age', [['百丽',13],['星耀',10]])
def test_api2(self, name,age): # 两个参数接收
print(name,age)
if __name__ == '__main__':
pytest.main(['test_api.py'])
3.1 YAML详解
-
yaml也是一种数据格式,支持注释,换行,裸字符串(最小的数据单位)
-
主要作用:
配置文件:环境,数据库信息,账号信息,日志格式,报告名称
用于接口自动化里面一些复杂的多接口串联
编写测试用例 -
yaml的语法规则
区分大小写
和python一样通过缩进的方式来表示层级关系(不同的是不能用tab键缩进,只能用空格)
# 表示注释 -
数据组成举例
map对象:键:(空格)值 name: 百丽
数组(列表):用 – 开头的
msxy
- name1: 百里
- name2: 星耀
- name3: 依然
[{name: 百丽},{name: 星耀}]
-
读取yaml的方法以及yaml的内容格式
可以随时在yaml中添加用例,一份数据就是一条用例,可以添加异常的用例,例如方法错误,值为空等
- get_token.yml
-
name: 获得统一的鉴权码token
request:
method: get
url: https://xxxx.com
date:
grant_type: client
appid: xxxweixin
secret: cotuao6249ao
validate: None
- yaml_util.py
# 读取测试用例的yaml文件的方法
def read_testcase_yaml(self,yaml_name):
with open(os.getcwd()+"/testcases/"+yaml_name,mode='r',encoding='utf-8') as f:
value = yaml.load(stream=f,Loader=yaml.FullLoader)
return value;
-
读取yaml
可以看到读取的内容是字典格式,可以通过key来获取值
# 测试yaml
# caseinfo 表示测试用例的信息
@pytest.mark.parametrize('caseinfo',YamlUtil().read_testcase_yaml('get_token.yml'))
def test_getValue(self,caseinfo):
print(caseinfo)
print(caseinfo['name'])
print(caseinfo['request']['method'])
print(caseinfo['request']['url'])
- 数据驱动:其实就是我们把测试用例的数据放到excel、yaml、csv、mysql,然后通过改变数据达到改变测试用例的执行结果
版权声明:本文为qq_41663996原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。