接口自动化---进阶

接口自动化---进阶导图预览 一 什么是接口自动化 让程序代替人工生产测试数据并判断响应的结果是否符合预期 作用 接口升级 迭代 时 会使用接口自动化测试 原则 只测试主要的或被重复使用的接口 功能测试需要所有接口 只需要设计正向数据 自动化测试可以被重复执行 多次执行

大家好,我是讯享网,很高兴认识大家。

导图预览
在这里插入图片描述
讯享网

一、什么是接口自动化

原则:

  • 只测试主要的或被重复使用的接口(功能测试需要所有接口)
  • 只需要设计正向数据
  • 自动化测试可以被重复执行,多次执行
  • 自动化测试时尽量不要使用关联,可以测试某个指定接口

总结:
自动化测试是对功能测试的补充,接口升级时,可以借助于自动化测试,检查升级前的接口实现是否能够正常运行。

二、为什么要做接口自动化?

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=

小讯
上一篇 2025-02-16 10:19
下一篇 2025-04-01 09:22

相关推荐

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