基于Requests与mitmproxy打造迷你接口测试框架
RESTful 是一种规范,符合 RESTful 的 Api 就是 RESTful Api。简单的说就是可联网设备利用 HTTP 协议通过 GET、POST、DELETE、PUT、PATCH 来操作具有 URI 标识的服务器资源,返回统一格式的资源信息,包括 JSON、XML、CSV、ProtoBuf、其他格式。
RESTful 的核心思想是,客户端发出的数据操作指令都是"动词 + 宾语"的结构。比如,GET /case 这个命令,GET 是动词,/case 是宾语。
接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。
很多系统的关联都是基于接口测试来实现的。可以将复杂的系统关联进行简化。并且可以提高测试用例的覆盖,相对容易实现自动化持续集成。
作为一名测试工程师,抓包是最常用的分析问题手段。抓包也有很多工具。比方:Windows下的Fiddler ,Postman。全平台的Charles等。我们比较推荐使用Charles 。它可以轻松记录浏览器和Internet之间的所有流量,是非常专业并基于Java开发网络http抓包工具软件。
熟练使用抓包工具,可以帮助我们节约时间提高工作效率。对于系统而言,也可以提高系统的健壮性。
本周霍格沃兹测试学院校长思寒,给我们带来了基于Requests与mitmproxy打造迷你接口测试框架公开课。这也是共抗疫情免费实战课程直播课的第三节。
用好Requests库是为了让我们更加方便的进行http相关的各种操作。让HTTP服务人类。而不同于 Fiddler 或 Wireshark 等抓包工具,mitmproxy 不仅可以截获请求帮助开发者查看、分析,更可以通过自定义脚本进行二次开发。
而思寒老师带来的新老版本响应结果自动化diff,让你轻轻松松将测试结果进行对比。可以重点查看两个版本之间相异之处。再也不需要将所有测试结果全部过一遍,省时省力效率高。
做测试时绝对逃不掉写测试用例。如果是在项目初期测试就参与进来,可以有足够多的时间去完善测试用例。
但若是项目紧、任务重的时候,测试项目就已经使出洪荒之力了,哪有时间和精力去写测试用例呢?但不写测试用例又无法交差。项目经理因为测试用例不到位迟迟无法交付,而测试工程师欲哭无泪啊!而自动生成测试用例的功能,让你再也不需要一条条去编写测试用例了。
接口自动化测试 | JsonPath 与 Mustache 请求传参的模板化技术
利器 | Java 接口自动化测试首选方案:REST Assured 实践 (一)
代理技术哪家强?接口 Mock 测试首选 Charles!
一文搞定 Postman 接口自动化测试
测试开发必备技能之 Dubbo 接口测试技术
接口自动化测试框架开发 (pytest+allure+aiohttp+ 用例自动生成)
从零开始打造企业定制化接口测试框架
工具在接口测试中发挥什么样的作用?
原文链接
获取更多技术文章分享
RESTful API简介
- RESTful 架构遵循统一接口原则,不论什么样的资源,都是通过使用相同的接口进行资源的访问。接口应该使用标准的 HTTP 方法如 GET ,PUT 和 POST ,并遵循这些方法的语义。
设计规范
- 常用的动词有以下 5 个
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HaQNlSYm-1650602920006)(https://ceshiren.com/uploads/default/original/3X/b/2/b2ae912065f18c6defdeb61ce6632aa78da1ea64.png)]
详情见 https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Spring Boot 实现 RESTful API
我们可以通过 Spring Boot 注解来实现 RESTful API 。
现在需要编写的是对一个用户的增删改查操作,如下表是一个非 RESTful 和 标准 RESTful 的对比表。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dCqbOOrW-1650602920756)(https://ceshiren.com/uploads/default/original/3X/c/f/cf8169f1871e202cc34bd8836679fc04a9eedf17.png)]
下面我们着重介绍下以下两对注解。
Controller 一般应用在有返回界面的应用场景下。例如,管理后台使用了模板技术如 thymeleaf 开发,需要从后台直接返回 Model 对象到前台,那么这时候就需要使用 Controller 来注解。
RestController 一般应用在只有接口的应用场景下. 例如开发前后端分离的项目时,通过 Ajax 请求服务端接口,那么接口就使用 RestController 统一注解。
需要注意的是 RestController 是 Controller 的子集。RestController 是 Spring4 后新加的注解,从 RestController 注解源码可以看出 RestController 是 Controller 和 ResponseBody 两个注解的结合体,即Controller=RestController+ResponseBody。
RestController 注解源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {@AliasFor(annotation = Controller.class)String value() default "";}
RequestMapping 和GetMapping/PostMapping/PutMapping/DeleteMapping 作用一样,其实可以相互替换,后者是前者的简化版本。
GetMapping 其实就等于将 RequestMapping 注解的 method 属性设置为 GET,PostMapping 其实就等于将 RequestMapping 注解的 method 属性设置为 POST,PutMapping、DeleteMapping 其实就等于将 RequestMapping 注解的 method 属性分别设置为 PUT、DELETE。
也就是说GetMapping、PostMapping、PutMapping、DeleteMapping 是 RequestMapping 的子集。
我们来看看 RequestMapping 的源码:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {String name() default "";//请求URI@AliasFor("path")String[] value() default {};@AliasFor("value")String[] path() default {};//请求类型,如 GET、POST、PUT、DELETE 等RequestMethod[] method() default {};//请求参数中必须包含某些参数值,才让该方法处理。String[] params() default {};//请求参数中必须包含某些指定的header值,才能让该方法处理请求。String[] headers() default {};//请求的内容类型(Content-Type),例如application/json, text/html;String[] consumes() default {};//响应的内容类型,仅当 request 请求头中的( Accept )类型中包含该指定类型才返回;String[] produces() default {};}
示例说明:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qlqXzjtH-1650602933158)(https://ceshiren.com/uploads/default/original/3X/2/7/271ca752b0844f2355a2f7f746e5d0ee7ade2066.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VsZyHSAL-1650602933954)(https://ceshiren.com/uploads/default/original/3X/f/d/fd89c9b47d9aecd44bfc489a091755731e49818a.png)]
- 新增 2 个文件:dto/UserDto.java 和 controller/HogwartsTestUserController.java ,其中 UserController 类中包括了对用户的 4 个操作增删改查。
- public class UserDto {
private String name;
private String pwd;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
/**
- RESTful API 风格示例 对资源 user 进行操作
- 本示例没有使用数据库,也没有使用 service 类来辅助完成,所有操作在本类中完成
- */
- @Api(tags = “霍格沃兹测试学院-用户管理模块”, hidden = true)
- @RestController
- @RequestMapping(“/api/user”)
- public class HogwartsTestUserController {
/**
* 查询用户列表,返回一个JSON数组
* * /
* @ApiOperation(“查询用户列表”)
* @GetMapping(“/users”)
* @ResponseStatus(HttpStatus.OK)
* public Object getUsers(){
* List list = getData();
* return list;
* }
/*
* 查询用户信息,返回一个新建的JSON对象
* * /
* @ApiOperation(“查询用户信息”)
* @GetMapping(“/users/{id}”)
* @ResponseStatus(HttpStatus.OK)
* public Object getUser(@PathVariable(“id”) Long id){
if(Objects.isNull(id)){
return null;
}
List list= getData();
UserDto userDto = getUserDto(id, list);
return userDto;
}
/*
* 新增用户
* * /
* @ApiOperation(“新增用户”)
* @PostMapping(“/users”)
* @ResponseStatus(HttpStatus.CREATED)
* public Object addUser(@RequestBody UserDto user){
List list= getData();
list.add(user);//模拟向列表中增加数据
return user;
}
/*
* 编辑用户
* * /
* @ApiOperation(“编辑用户”)
* @PutMapping(“/users/{id}”)
* @ResponseStatus(HttpStatus.CREATED)
* public Object editUser(@PathVariable(“id”) Long id,@RequestBody UserDto user){
* List list = getData();
* for (UserDto userDto:list) {
* if(id.equals(userDto.getId())){
* userDto = user;
* break;
* }
* }
return user;
}
/*
* 删除用户
* * /
* @ApiOperation(“删除用户”)
* @DeleteMapping(“/users/{id}”)
* @ResponseStatus(HttpStatus.NO_CONTENT)
* public Object deleteUser(@PathVariable(“id”) Long id){
* List list = getData();
* UserDto userDto = getUserDto(id, list);
* return userDto;
* }
/*
* 模拟数据
* * /
* private List getData(){
* List list=new ArrayList<>();
UserDto userDto = new UserDto();
userDto.setId(1L);
userDto.setName(“admin”);
userDto.setPwd(“admin”);
list.add(userDto);
userDto = new UserDto();
userDto.setId(2L);
userDto.setName(“HogwartsTest1”);
userDto.setPwd(“HogwartsTest1”);
list.add(userDto);
userDto = new UserDto();
userDto.setId(3L);
userDto.setName(“HogwartsTest2”);
userDto.setPwd(“HogwartsTest2”);
list.add(userDto);
userDto = new UserDto();
userDto.setId(4L);
userDto.setName(“HogwartsTest3”);
userDto.setPwd(“HogwartsTest3”);
list.add(userDto);
return list;
}
/*
* 模拟根据id查询列表中的数据
* * @param id
* * @param list
* * @return
* */
* private UserDto getUserDto( Long id, List list) {
* UserDto UserDto = null;
* for (UserDto user : list) {
* if (id.equals(user.getId())) {
* UserDto = user;
* break;
* }
* }
* return UserDto;
* }
* }
获取全部资源 获取所有用户GET http://127.0.0.1:8081/api/user/users/响应参数
[
{
“id”: 1,
“name”: “admin”,
“pwd”: “admin”
},
{
“id”: 2,
“name”: “HogwartsTest1”,
“pwd”: “HogwartsTest1”
},
{
“id”: 3,
“name”: “HogwartsTest2”,
“pwd”: “HogwartsTest2”
},
{
“id”: 4,
“name”: “HogwartsTest3”,
“pwd”: “HogwartsTest3”
}
]
获取单个资源 获取用户GET http://127.0.0.1:8081/api/user/users/3新增一个资源 新增一个用户POST http://127.0.0.1:8081/api/user/users请求参数
{
“id”: 4,
“name”: “HogwartsTest5”,
“pwd”: “HogwartsTest5”
}
编辑更新一个资源PUT http://127.0.0.1:8081/api/user/users/3请求参数
{
“name”: “HogwartsTest6”,
“pwd”: “HogwartsTest6”
}
删除一个资源DELETE http://127.0.0.1:8081/api/user/users/3下面介绍一些 Spring Boot 常用配置项,通过这些常用配置项,我们可以修改 Spring Boot 的一些默认配置。
修改服务默认端口:
server:
port: 8093
指定服务名称:
spring:
application:
name: aitest
多环境配置
spring:
profiles:
active: dev
![](https://img-blog.csdnimg.cn/img_convert/28131392c4359c998e14e7319e8c38c5.png)
如上图新建 application-dev.yml、application-test.yml、application-uat.yml、application-prod.yml 四套配置文件环境,我们在四套配置文件中将设置服务端口号分别设置为 8091/8092/8093/8094。然后启动服务,可以看到服务的端口号会和 application.yml 中激活的环境配置信息一致。
[原文链接](https://mp.weixin.qq.com/s?__biz=MzU3NDM4ODEzMg==&mid=2247500353&idx=1&sn=bb39d3b6f0c66d44127bda128b120c70&chksm=fd31a08aca46299cd5dd55444f621509cf838be769127fd790c4fb99d35e9cff5d00f4e3dca4#rd) [获取更多技术文章分享](https://qrcode.ceba.ceshiren.com/link?name=article&project_id=qrcode&from=csdn2×tamp=1650602598)
基于Requests与mitmproxy打造迷你接口测试框架相关推荐
- 三百行python代码的项目_300行Python代码打造实用接口测试框架
在刚开始实现ApiTestEngine的时候,卡斯(kasi)提议做一个Java版的.对于这样的建议,我当然是拒绝的,瞬即回复了他,"人生苦短,回头是岸啊". 当然,我没好意思跟他 ...
- java elf_GitHub - lyz362502/Java-elf: Java-elf是一个轻量级接口测试框架
理论知识不能丢 参考搜狗测试 什么是框架 总结:测试框架是测试开发过程中提取特定领域测试方法共性部分形成的体系结构,并不是一个现成可用的系统, 需要测试工程师在它基础上结合自己的测试对象转换为自己的测 ...
- python数据接口设计_基于python的接口测试框架设计(一)连接数据库
基于python的接口测试框架设计(一)连接数据库 首先是连接数据库的操作,最好是单独写在一个模块里, 然后便于方便的调用,基于把connection连接放在__init__()方法里 然后分别定义D ...
- requests+pytest+allure接口测试框架搭建
文章目录 requests+pytest+allure接口测试框架搭建 一.创建项目![在这里插入图片描述](https://img-blog.csdnimg.cn/969aa95077fc447c9 ...
- CSDN【top1】Pytest接口测试框架实战项目搭建
一.前言 想想之前玩的框架,做的项目都是把数据用例冗余到一起的,不符合数据用例分离的思想,所以准备基于pytest搭建个测试框架,支持数据用例分离,接下来会用一系列文章逐步介绍整个框架是怎么搭建起来的 ...
- 基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台
作者 | 陈厚道 冯庆 来源 | 阿里巴巴云原生公众号 导读:本文将对 RocketMQ-Exporter 的设计实现做一个简单的介绍,读者可通过本文了解到 RocketMQ-Exporter 的实 ...
- CVPR 2019开源论文 | 基于“解构-重构”的图像分类学习框架
作者丨白亚龙 单位丨京东AI研究院研究员 研究方向丨表示学习.图像识别 基于深度卷积图像识别的相关技术主要专注于高层次图像特征的理解,而对于相似物体之间的细节差异和具有判别意义的区域(discrimi ...
- 基于Spring开发的DUBBO服务接口测试
基于Spring开发的DUBBO服务接口测试 知识共享主要内容: 1. Dubbo相关概念和架构,以及dubbo服务程序开发步骤. 2. 基于Spring开发框架的dubbo服务接口测试相关配置. 3 ...
- 基于Asp.Net Core打造轻量级内部服务治理RPC(一)
继之前的<Asp.Net Core + Docker 搭建>文章末尾说过的,将陆续编写基于asp.net core 打造一个内部服务治理的rpc框架.不过前端时间较忙,所以搁置了一段时间. ...
最新文章
- 蓝桥杯第七届决赛真题大全题解(java版本)
- 产线数字化软件源码_数字化工厂规划的十大核心要素
- wxWidgets:wxChoice类用法
- 哈工大威海c语言实验报告 第八章 无法运行程序,哈工大威海c语言实验报告.doc...
- 第三篇.python编辑器和集成环境01
- python求非线性优化问题_用python优化非线性函数
- grafana zabbix 模板_Grafana + Zabbix 监控系统搭建
- 怎么用class覆盖style样式
- Webpack入门教程二
- javascript 数组合并与去重
- cpu顶盖怎么看步进_【有趣】第19期:如何从CPU顶盖获取有用信息(上)?
- 苹果手机如何投屏到电脑【无线有线】
- 我的游戏测试面试过程
- 计算机的正确使用方法,电脑开关机的正确的操作步骤顺序(不会对电脑造成任何损坏)...
- 2021年软件测试工具总结——十大新UI功能测试工具
- ncre计算机职业英语,NCRE计算机职业英语一级考试样卷.doc
- 解决联想拯救者Y7000安装ubuntu系统wifi无法连接以及关机卡死问题
- linux应用/软件设置为系统服务
- P2905 [USACO08OPEN]农场危机Crisis on the Farm
- Pointnet语义分割任务S3DIS数据集上的注意点