导图预览

讯享网
一、什么是接口自动化
原则:
- 只测试主要的或被重复使用的接口(功能测试需要所有接口)
- 只需要设计正向数据
- 自动化测试可以被重复执行,多次执行
- 自动化测试时尽量不要使用关联,可以测试某个指定接口
总结:
自动化测试是对功能测试的补充,接口升级时,可以借助于自动化测试,检查升级前的接口实现是否能够正常运行。
二、为什么要做接口自动化?
1.接口数量大,敏捷开发,团队实现接口测试,版本控制
2.有些接口工具无法实现(加密的复杂接口,签名接口等)
3.处理不同协议的接口
4.提供更简洁明了的报告
5.多接口串联,数据库验证,日志监控
6.web自动化+接口自动化同时做的时候。
三、python+requests模块
requests第三方库,主要用于发送http请求,做接口自动化。
json和data的区别:
json: 数据报文:不管是dict还是str类型,默认都是application/json,格式:{“a”:1,"b":2} 一般只能传dict格式的。 data: 数据报文:dict字典类型,那么默认情况下请求头:application/x-www-form-urlencoded; 以form表单的方式传参,格式:a=1&b=2 数据报文:str类型,那么默认情况下是:text/plain
讯享网
若在其他情况下,没法直接传参,那么可以将对应的参数转换为属性支持的参数格式:
- json.dumps(data) 序列化:将字典格式的数据转换成str格式
- json.loads(data) 反序列化:把str格式转换成字典格式
通过requests做接口自动化
讯享网import requests from pprint import pprint res=requests.get('http://localhost/mgr/ps/mgr/index.html#/') if res.status_code==200: print('测试通过') else: print('接口存在问题') print(res.json()) #将结果以json形式展示
import requests from pprint import pprint res=requests.post('http://localhost/apijson/mgr/sq_mgr/', data={
"action" : "add_course", "data" : '''{
"name":"初中化学", "desc":"初中化学课程", "display_idx":"4" } ''' }) retobj=res.json() if retobj['retcode']==0: print('测试通过') else: print('接口存在问题') pprint(res.json(),width=30)
带请求头和cookies的接口需要cookie鉴权,有两种方式:
1.网页的接口基本上都要做cookie鉴权
2.通过session实现cookie鉴权----常用方式
封装请求
接口自动化框架封装的第一步,统一请求方式。
requests.request()
例:
讯享网req=requests.request("post",url=url,data=data,headers=headers)
class Test_phpwind: cookies="" csrf_token="" #设置一次会话session,相当于保存一个身份鉴权,用于整个会话访问过程 session=requests.session() def test_firstPage(): url='http://47.107.116.139/phpwind/' req=Test_phpwind.session.request("get",url=url) # print(req.text) reg='name="csrf_token" value="(.*?)"' Test_phpwind.csrf_token=re.search(reg,req.text)[1] print(Test_phpwind.csrf_token) Test_phpwind.cookies=req.cookies print(Test_phpwind.cookies) def test_login(): url="http://47.107.116.139/phpwind/index.php?m=u&c=login&a=dorun" data={
"username":"ashley", "password":"zxcvbnm...", "backurl":"http://47.107.116.139/phpwind/", "invite":"", "csrf_token":Test_phpwind.csrf_token } headers={
"Accept": "application/json, text/javascript, */*; q=0.01", "X-Requested-With": "XMLHttpRequest" } print("+"*10) print(Test_phpwind.csrf_token) print(Test_phpwind.cookies) req=Test_phpwind.session.request("post",url=url,data=data,headers=headers) print("----------------") print(req.json()) if __name__=="__main__": # pytest.main(['-vs']) Test_phpwind.test_firstPage() Test_phpwind.test_login()
接口关联的封装
讯享网主要case代码: test.py import re import requests from readYaml import readYaml class Test_phpwind: session=requests.session() def test_firstPage(): url='http://47.107.116.139/phpwind/' req=Test_phpwind.session.request("get",url=url) # print(req.text) reg='name="csrf_token" value="(.*?)"' csrf_token=re.search(reg,req.text)[1] data={
"csrf_token":csrf_token} # 为什么穿不了参数,提示没有传data,实际上有了呀? # readYaml.readYaml.write_contract_yaml(data) readYaml().write_contract_yaml(data) def test_login(): # 整个一直报错是因为从yaml中获取到的是一个dict类型,需要获取token值即可 # csrf_token=readYaml().read_contract_yaml("csrf_token") csrf_token=readYaml().read_contract_yaml("csrf_token")['csrf_token'] print("="*10) print(csrf_token) url="http://47.107.116.139/phpwind/index.php?m=u&c=login&a=dorun" data={
"username":"ashley", "password":"zxcvbnm...", "backurl":"http://47.107.116.139/phpwind/", "invite":"", "csrf_token":csrf_token } headers={
"Accept": "application/json, text/javascript, */*; q=0.01", "X-Requested-With": "XMLHttpRequest" } print("+"*10) req=Test_phpwind.session.request("post",url=url,data=data,headers=headers) print("----------------") print(req.json()) if __name__=="__main__": # pytest.main(['-vs','--reruns=3']) Test_phpwind.test_firstPage() Test_phpwind.test_login()

import os import yaml class readYaml: #读取yaml文件 def read_contract_yaml(self,params): with open(os.getcwd()+'/contract.yaml',mode='r',encoding="utf-8") as f: value=yaml.load(stream=f,Loader=yaml.FullLoader) return value; #写入yaml文件内容 def write_contract_yaml(self,data): with open(os.getcwd()+"/contract.yaml",mode='w',encoding='utf-8') as f: yaml.dump(data=data,stream=f,allow_unicode=True) def clear_yaml(): with open(os.getcwd()+"/contract.yaml",mode='r',encoding='utf-8') as f: f.truncate() print("清除yaml内容")
conftest文件
讯享网conftest.py import pytest import readYaml @pytest.fixture(scope="function") def conn_database(): print('连接数据库') yield print("关闭数据库") def clear_yaml(): readYaml.readYaml.clear_yaml()
断言
通过断言来判断接口是否通
def test_login(self): # 整个一直报错是因为从yaml中获取到的是一个dict类型,需要获取token值即可 # csrf_token=readYaml().read_contract_yaml("csrf_token") csrf_token=readYaml().read_contract_yaml("csrf_token")['csrf_token'] print("="*10) print(csrf_token) url="http://47.107.116.139/phpwind/index.php?m=u&c=login&a=dorun" data={
"username":"ashley", "password":"zxcvbnm...", "backurl":"http://47.107.116.139/phpwind/", "invite":"", "csrf_token":csrf_token } headers={
"Accept": "application/json, text/javascript, */*; q=0.01", "X-Requested-With": "XMLHttpRequest" } req=Test_phpwind.session.request("post",url=url,data=data,headers=headers) print(req.json()) result=req.json() assert result["state"] in "success" assert 'refresh' in result
yaml文件
yaml主要用于配置文件,或者用例文件或者保存接口关联的值。主要的数据有以下两种:
- map对象:键值对:name:value
- 列表类型:用 - 开头的
讯享网- name:xxx - request:xxx - url:xxx
yaml文件的规则
1.必须包含一级关键字:name,request,validate
2.在request关键字下必须包括method、url、data,如果没有data的话,那么输出默认值。
3.提取变量使用以及关键字:extract 。支持json提取和正则提取(.+?)或(.*?),取值使用{
{ }}
4.可以使用热加载的方式调用debug_talk.py中的DebugTalk类里面的方法。通过${ }调用方法
5.支持equals,contains两种断言
6.使用parameters做csv文件的数据驱动,通过$csv{appid}这种格式取值
例:
parameters: name-appid-secret-grant_type-assert_str:data/get_token_data.csv
讯享网- name:获取鉴权码token request: method:get url: data: grant_type:xxx validate: - equals:{
status_code:200} - contains:asscess_token
语法规则:
1、区分大小写
2、支持注释,用#注释
3、使用缩进判断层级关系
对接口参数的判断

使用DDT实现自动化
数据驱动的数据源可以时csv、excel、txt、数据集合以及数据库等形式。
优点:
- 能够减少代码重复
- 一条用例失败,不会影响其他测试数据对应的用例
DDT的使用步骤:
1、使用@ddt装饰你的测试类
2、使用@data或@file_data装饰需要数据驱动的测试方法
3、如果一组数据中有多个参数,可以通过@unpack装饰测试方法来达到解包效果,然后通过变量来接收
代码实现:
from ddt import ddt,data @ddt #ddt一定是装饰在TestCase的子类上 class Test_phpwind(unittest.TestCase): session=requests.session() host='http://120.55.190.222:9090' #测试登录接口 #获取excel数据,*号代表返回的是可变参数 @data(*ExcelUtils().get_excelData()) @unpack #对每一组数据,如果是list或tuple形式,将他们分拆成独立的参数 def test_01_login(self,index,username,pwd,ranCode): print(index,username,pwd,ranCode) url1=self.host+"/loginController.do?login2" url=self.host+"/loginController.do?checkuser" data={
"returnUrl": None, "userName":username, "password":pwd, "randCode":ranCode } headers={
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest" } req1=self.session.request("post",url=url1,data=data,headers=headers) req2=self.session.request("post",url=url,data=data,headers=headers) print( req2.content.decode("utf-8")) result=json.loads(req2.content.decode("utf-8")) print(result['msg']) if index==1: assert '操作成功' in result['msg'] print(result['msg']) else: assert bool("false") in result['success'] print(result['msg'])
注意:data中的参数函数返回值一定需要遵守ddt.data()可接受的数据格式,即:一组数据,每个数据为单个的值;多组数据,每组数据为一个列表或一个字典。
接口自动化需要了解的知识:

httprunner知识见:https://editor.csdn.net/md?not_checkout=1&spm=1011.2124.3001.6192&articleId=
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/75086.html