1.接口测试框架设计(python,requests库,unittest)---必须掌握
-
common
-
send_method.py # 封装接口请求方式
-
编写依据
-
项目的接口文档
-
接口三要素
""" send_method.py 1.封装接口请求方式----依据接口文档,不同的项目,send_method也不太一样 2.封装思路---结合接口三要素 请求方式+请求地址 请求参数 返回值 3.实例 结合学生管理系统项目--接口文档,封装send_method """ import requests import json class SendMethod: """ 学生管理系统: 请求方式:get,post,put,delete 请求参数:get/delete:parmas post/put:json 返回值类型:json """ @staticmethod # 静态方法不需要实例化,使用方式 : 类名.静态方法 def send_method(method, url, params=None, data=None): """ 根据学生管理系统接口文档,封装请求方式 :param method: 请求方式 :param url: 请求地址 :param params: get/delete请求参数 :param data: post/put请求参数 :return: """ if method == "get" or method == "delete": # 当请求方式为get或delete时 response = requests.request(method=method,url=url,params=params) elif method == "post" or method == "put": # 当请求方式为post或put时 response = requests.request(method=method,url=url,json=data) else: print("请求方式不正确!") response = None if method == "delete": return response.status_code # 如果请求方式是delete,只返回状态码 else: return response.json() @staticmethod def format_response(response): """ 格式化返回数据 :param response: 返回数据 :return: """ return json.dumps(response, indent=2, ensure_ascii=False) if __name__ == '__main__': url = "http://127.0.0.1:8000/api/departments/" method = "get" params = {"$dep_id_list":"11,12,13"} res = SendMethod.send_method(method=method,url=url,params=params) print(type(res)) print(type(SendMethod.format_response(res)))
-
-
-
get_keyword.py # 在接口返回值中通过关键字获取对应值
""" get_keyword.py 在接口返回值中,通过关键字获取对应值 1.需要安装一个库:jsonpath pip install jsonpath 2.jsonpath的使用 jsonpath.jsonpath(源数据,jsonpath表达式) jsonpath表达式:$..关键字 """ # 1.导入jsonpath库 import jsonpath # 2.源数据 # data = { # "count": 3, # "next": None, # "previous": None, # "results": [ # { # "dep_id": "11", # "dep_name": "迦南学院_1", # "master_name": "司马光_1", # "slogan": "不许迟到" # }, # { # "dep_id": "12", # "dep_name": "迦南学院_2", # "master_name": "司马光_2", # "slogan": "不许迟到" # }, # { # "dep_id": "13", # "dep_name": "迦南学院_3", # "master_name": "司马光_3", # "slogan": "不许迟到" # } # ] # } # 3.根据关键字查找对应值 # print(jsonpath.jsonpath(data, "$..dep_name")) # python语言实现 # print(data["results"][0]["dep_id"]) # 封装通过关键字获取对应值 class GetKeyword: @staticmethod def get_value_by_keyword(data, keyword): """ 通过关键字,获取对应的值 只获取一个,如果有多个,获取第一个,找到后返回关键字所对应的值,没有返回False :param data: 数据源(接口返回值) :param keyword: 关键字 :return: """ return jsonpath.jsonpath(data,f"$..{keyword}")[0] @staticmethod def get_values_by_keyword(data, keyword): """ 通过关键字,获取一组数据 :param data: 数据源(接口返回值) :param keyword: 关键字 :return: """ return jsonpath.jsonpath(data, f"$..{keyword}") if __name__ == '__main__': data = '''{ "count": 3, "next": None, "previous": None, "results": [ { "dep_id": "11", "dep_name": "迦南学院_1", "master_name": "司马光_1", "slogan": "不许迟到" }, { "dep_id": "12", "dep_name": "迦南学院_2", "master_name": "司马光_2", "slogan": "不许迟到" }, { "dep_id": "13", "dep_name": "迦南学院_3", "master_name": "司马光_3", "slogan": "不许迟到" } ] } ''' data_1 = "{'naem':123,'age':'2'}" data_1.keys() print(GetKeyword.get_value_by_keyword(data_1, "age"))
-
-
interface
-
一个接口对应一个.py文件或一类接口
-
对该接口的请求 --- 用于单接口测试
-
根据业务获取接口返回值 --- 用于关联接口测试
""" add_department.py # 添加学院 函数/方法调用时参数顺序问题: 原方法: def send_method(method, url, params=None, data=None) 调用方法: send_method(a,b,c,d) 1.当没有指定时,按照函数参数的顺序传入 2.当指定时,按照制定的值传入 """ from common.send_method import SendMethod from common.get_keyword import GetKeyword class AddDepartment: def __init__(self,method="post"): self.url = "http://127.0.0.1:8000/api/departments/" self.method = method def add_dep(self,data): """ 请求新增学院接口,针对单接口测试 """ response = SendMethod.send_method(method=self.method,url=self.url,data=data) return response def get_depid(self,data): """ 获取添加成功后的dep_id,为关联接口测试准备 """ response = self.add_dep(data) # 获取新增学院接口返回值中的dep_id dep_id = GetKeyword.get_value_by_keyword(response["create_success"],"dep_id") return dep_id if __name__ == '__main__': data = { "data": [ { "dep_id":"T110", "dep_name":"Test_dep", "master_name":"Test-Master", "slogan":"" } ] } print(AddDepartment().add_dep(data))
-
-
-
script
-
测试用例
""" test_add_dep.py """ import unittest # 测试用例是在unittest框架下编写 from interface.add_department import AddDepartment # 测试添加学院接口 from common.get_keyword import GetKeyword from common.operation_excel import OperationExcel import ddt oper = OperationExcel("../data/add_dep.xls") test_data = oper.get_data_by_index() @ddt.ddt class TestAddDep(unittest.TestCase): def setUp(self): self.add_dep = AddDepartment() @ddt.data(*test_data) def test_add_dep(self,data): """测试成功添加学院""" request_data = { "data": [ { "dep_id":data["dep_id"], "dep_name":data["dep_name"], "master_name":data["master_name"], "slogan":data["slogan"] } ] } response = self.add_dep.add_dep(request_data) # 得到新增学院的接口返回值 # 获取添加成功后的dep_id # self.add_dep.get_depid(data) # 因为直接使用该方法相当于又执行了一次添加学院接口 if "status_code" in response.keys(): # 判断status_code是否在返回值的键中 res = GetKeyword.get_value_by_keyword(response, "status_code") else: res = GetKeyword.get_value_by_keyword(response["create_success"],"dep_id") # print(res) # print(data["expect"]) self.assertEqual(res,data["expect"]) # 断言实际获取到的数据和预期的数据做比较 """ # 返回值的验证有3种情况 # 1.添加成功 # 2.添加id已存在的学院 # 3.参数错误 根据对接口文档的分析 可以通过判断返回值是否包含"status_code"区分1,2和3,然后 区分1和2; 根据返回值中already_exist.count是否为0,判断是否添加成功 # 条件判断的个数,根据接口文档返回值的情况来决定 if "status_code" in response.key(): # 判断status_code是否在返回值的键中 res = GetKeyword.get_value_by_keyword(response,"status_code") else: if GetKeyword.get_value_by_keyword(response["already_exist"],"count") == 0: res = GetKeyword.get_value_by_keyword(response["create_success"],"dep_id") else: res = GetKeyword.get_value_by_keyword(response["already_exist"],"dep_id") expect = "预期结果" self.assertEqual(res,expect) """ if __name__ == '__main__': unittest.main()
-
-
data----测试数据,配置文件
-
report----测试报告
2.mock(了解)
-
作用 在接口没有完成的情况下,根据接口文档模拟真正接口
-
使用在和第三方接口对接
-
使用步骤
-
需要java环境
-
需要moco-runner-0.12.0-standalone.jar # mockserver
-
启动 mock_server
-
java -jar moco-runner-0.12.0-standalone.jar http -p 12306 -c dep.json
-
json文件和jar包在同一目录下
-
在该目录下进入cmd
-
-p 12306:指启动mock_server服务的端口号
-
-c dep.json:指启动指定的json文件
-
启动成功后,访问地址:
-
-
-
3.使用python发邮件zmail库(熟悉)
-
1.设置邮箱授权码(163,qq)
-
2.安装zmail库
-
pip install zmail
-
-
3.编写发送邮件脚本
-
1.导入zmail
-
2.编辑邮件内容
-
字典格式
-
邮件标题:subject
-
邮件正文(文本格式):content_text
-
邮件正文(html):content_html
-
邮件附件:attachments:"文件路径"
-
-
-
3.启动邮件服务
-
server = zmail.server(发件人邮箱,发件人邮箱授权码)
-
-
4.发送邮件
-
server.send_mail(收件人,邮件内容)
-
当给多人发送:收件人:列表格式[收件人1,收件人2]
-
-
4.持续集成(了解)
5.接口安全机制(熟悉)
5.1用户认证(用的少)
-
在请求某个接口的时候需要授权
-
如果没有授权表示权限不够无法访问
5.2数字签名
-
特点:
-
sign,ticket
-
作为参数传入的
-
不参与业务逻辑
-
作为凭证
-
-
数字签名构成
-
密钥secretkey
-
需要对参数进行排序
-
MD5加密(32位长)
-
全取
-
取16
-
前16
-
后16
-
8-24位
-
-
-
base64编码
-
5.3加密方式
-
对称加密
-
加密和解密的密钥是同一个
-
加密速度快,方便
-
用户体验好
-
密钥有泄漏的风险
-
-
非对称加密
-
加密和加密的密钥不一样,加密的密钥叫做公钥(客户端),解密的密钥私钥(服务端)
-
加密速度慢
-
安全性高
-
用户体验差
-
-
怎样平衡对称加密非对称加密
-
对密钥进行非对称加密
-
对其他参数使用对称加密
-
5.4加密接口测试步骤
-
加密方法
-
MD5,AES,RSA
-
-
加密规则
-
对哪些参数进行加密
-
对参数是否进行排序
-
转码方式是什么base64
-
-
编写加密/解密代码
-
发起请求