接口自动化测试
框架结构
login.py—业务模块
"""
规划接口
示例:
接口名称:登录接口
接口类型:token机制(有些项目是cookies--sessionid机制)
用途:
1.本身需要做接口测试
2.获取token,给后续的接口做鉴权
"""
import hashlib
from pprint import pprint
import requests
from configs.config import HOST
# 封装一个md5加密函数
def get_md5(psw):
"""
:param psw: 密码
:return: 返回经过md5加密的结果
"""
# 实例化一个md5对象
md5 = hashlib.md5()
# 调用加密方法直接加密
md5.update(psw.encode("utf-8"))
return md5.hexdigest() # 得到一个经过md5加密的32位16进制数
# 封装一个登录类
class Login:
# 登录方法
def login(self, inData, mode=True):
# url路径
url = f'{HOST}/api/loginS'
# 将inData参数里的密码改成md5加密后的结果
inData["password"] = get_md5(inData["password"])
# 参数
"""
参数类型:
data------一般是表单格式
json------json
files-----文件上传接口
params------参数会放到url路径里,如:?a=1&b=2
"""
payload = inData
# 请求
resp = requests.post(url, json=payload) # 这里看接口的请求参数具体是什么类型,就用什么类型的传参
# 查看响应
# return resp.text # 返回一个文本类型(如果一开始不知道响应数据的类型,可以使用text)
if mode: # 获取token
return resp.json()['token']
else: # 获取整个响应数据
return resp.json() # 返回json格式的结果(这里我们已经知道响应数据类型(根据开发的接口文档),所以可以这么用,如果不知道响应数据类型,最好使用text)
if __name__ == '__main__':
resp = Login().login({'username': '20154084', 'password': '123456'})
pprint(resp)
config.py----基本配置
HOST = 'http://121.41.14.39:9097' # 环境参数
loginCase.yaml----用例数据
# 登录接口用例
- #公用数据
url: /api/loginS
method: POST
#用例参数化
- #用例1
detail: 账号与密码都正确
data: #请求数据
username: "20154084"
password: "123456"
resp: #预期的响应结果中的code和message信息
code: 200
message: "登录成功"
- #用例2
detail: 账号没有,密码都正确
data:
username: ""
password: "123456"
resp:
code: 400
message: "用户名不存在"
yamlControl.py-----读取yaml文件的工具文件
# 需要安装一个第三方库 PyYAML
from pprint import pprint
import yaml
def get_yaml_data(filePath):
res_list = [] # 存放用例结果[(请求1,期望结果1),(请求2,期望结果2)]
# 1.读取文件----从磁盘读取文件到内存
fo = open(filePath, 'r', encoding="utf-8") # 这里打开文件操作是在函数内部,当函数调用完毕后会被自动释放,所以可以不用关闭文件
# 2.使用yaml方法获取数据
res = yaml.load(fo, Loader=yaml.FullLoader) # 全局加载
public_info = res[0] # 可以封装基类使用
del res[0]
for one in res:
res_list.append((one['data'], one['resp']))
return res_list
if __name__ == '__main__':
res = get_yaml_data('../data/loginCase.yaml')
print(res)
test_login.py-------测试模块
from utils.yamlControl import get_yaml_data
from libs.login import Login
import pytest
import allure
import os
# 执行用例
# 1.获取用例数据
# use_case_data = get_yaml_data('../data/loginCase.yaml')[1]
# # 2.调用接口方法---获取响应数据
# resp_data = Login().login(use_case_data['data'], False)
# print(resp_data)
# # 3.断言 实际响应与预期数据的对比
# if resp_data['message'] == use_case_data['resp']['message']:
# print('----用例通过----')
# def test_001():
# print('例子在控制台被打印了')
# assert 1 == 2
"""
测试登录接口
1.需要请求参数(也就是登录所需要的账号和密码,在用例里面可以获取,在yaml文件)
2.需要预期结果(用来和实际响应结果作比较),也在用例里面,即yaml文件中
请求参数(帐号密码)就是下面的inData
预取结果就是下面的expData['message']
数据驱动原型
@pytest.mark.parametrize('a',[1,2])-----这里有两组数据,a=1是一组数据,a=2是一组数据,总共测了两次
def test_001(a):-----这里要传入参数a
assert 1 == a
@pytest.mark.parametrize('a,b',[(x1,y1),(x2,y2),(x3,y3)]-----这里有三组数据,每组a对应x,b对应y
def test_002(a,b)
pass
"""
# 登录接口-测试类封装
class TestLogin:
@pytest.mark.parametrize('inData,expData', get_yaml_data('../data/loginCase.yaml'))
def test_login(self, inData, expData):
res = Login().login(inData, False) # 传入请求数据(账号密码),获得整个响应数据
assert res['message'] == expData['message'] # 使用预取结果与实际响应比较
if __name__ == '__main__':
# -s 表示在控制台打印输出,-q表示打印简化的信息,--alluredir表示生成allure报告,最后的路径表示allure报告原始文件的存放路径
pytest.main(["test_login.py", "-sq", "--alluredir", "../report/raw"])
# 使用allure原始文件生成报告
os.system("allure serve ../report/raw")
"""
allure报告原理:
1.生成报告的原始文件
2.将原始文件生成报告
"""
conftest.py----固件函数模块
注意该模块(py文件)必须放在与测试模块同一个目录下,且文件名是固定的
"""
- 函数start_running()跟setUp()和tearDown()用法差不多,不过用fixture装饰器要好一些
- 该py文件的名字必是conftest.py,固定的不能变,且要放在test_cases目录下,和测试模块在一起,对应@pytest.fixture()中的scope作用域为包级别---session
- yield是生成器,到了yield这里函数会直接返回,相当与return
- @pytest.fixture()是固件函数
"""
import pytest
@pytest.fixture(scope="session", autouse=True) # session表示包级别
def start_running():
# 自动化测试前的环境初始化操作
print('---准备开始自动化测试任务----')
yield
# 自动化测试完成之后,做数据清理工作
print('----自动化测试完成,开始清理垃圾数据-----')