技术分享 | 如何确保API 的稳定性与正确性?你只需要这一招

news2024/11/16 7:35:28

现在,越来越多的 Web 应用转向了RESTful的架构,很多产品和应用暴露给用户的往往就是一组 REST API,这样有一个好处,用户可以根据需要,调用不同的 API,整合出自己的应用出来。从这个角度来讲,Web 开发的成本会越来越低,人们不必再维护自己的信息孤岛,而是使用 REST API 这种组合模式。

image1080×804 50 KB

那么,作为 REST API 的提供者,如何确保 API 的稳定性与正确性呢?全面系统的测试是必不可少的。Java 程序员常常借助于 JUnit 来测试自己的 REST API,不,应该这样说,Java 程序员常常借助于JUnit 来测试 REST API的实现!从某种角度来说,这是一种“白盒测试”,Java 程序员清楚地知道正在测试的是哪个类、哪个方法,而不是从用户的角度出发,测试的是哪个REST API。

image1080×654 61.1 KB

Rest-Assured 是一套由 Java 实现的 REST API测试框架,它是一个轻量级的REST API 客户端,可以直接编写代码向服务器端发起 HTTP请求,并验证返回结果;它的语法非常简洁,是一种专为测试 REST API 而设计的 DSL。使用 Rest-Assured 测试 REST API,就和真正的用户使用 REST API 一样,只不过 Rest-Assured 让这一切变得自动化了。

image1073×733 49.6 KB

模拟get请求

雪球网是一个股票投资网站,你可以使用网站的搜索功能来查询股票信息,比如我们想查询sougou的信息,下 面利用了charles分析工具来查看请求和回答:

image2124×1170 400 KB

这是一个Get请求,返回的内容格式如下:

现在,我们使用 Rest-Assured 来编写一个简单的测试程序调用相同的Get请求:

  • 第一步,我们要判断这是什么格式数据:json
  • 第二步,确定请求地址:从charles的结果中获取y为https://xueqiu.com/stock/search.json

tmp1064×275 24.7 KB

  • 第三步,填写表单:从chrome浏览器检查结果中查询request的query信息是code:sougou

我们的代码也很简单:

返回的结果却很残酷:

tmp1080×274 38.9 KB

与登陆账号,刷新页面有关的话,我首先想到了cookie,网站都用cookie来保存账号相关信息,于是加入 cookie:

返回结果正确,你问我惊不惊喜,老实回答,不惊喜。因为我搞不明白为什么一个查询需要Cookie验证,如果不加Cookie,返回的信息却是没有登陆!

image899×974 72.4 KB

显然,我的Cookie并不包含登陆信息,因为我压根就没有登陆,当然这是网站的设计,与Rest-assured无关。

1080×474 70 KB


更进一步

怎么区别xml与json

image942×679 33.3 KB

答:你看就知道了嘛,xml长这个样子

json长这个样子

given,when,then分别是什么

image965×707 32 KB

答:given用于放置需要的参数,比如上面例子中,我将访问参数:code和cookie放到了given里;when用于填 写要访问的url;then进行断言,来来判断结果是否正确。

模拟post请求

有的时候,我们想提交表单,这种情况下使用get会非常被动,于是post登场了。

下面是代码。

我相信此时你的内心是这样的。

别着急,下面我会讲清楚…

在我大万维网世界中,TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是 如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,非常紧急的警车可能被前面的汽车拦堵在路上,整个交通系统一定会瘫痪。

image1080×806 75.6 KB

为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里。当然,你也可以在GET的时候往车厢内偷偷藏点货物,但是这是很不光彩;也可以在POST的时候在车顶上也放一些数据,让人觉得傻乎乎的。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。

image1080×818 81.4 KB

使用断言

使用EqualTo

在前面,我们使用了EqualTo判断值是否是“搜狗”:

它的作用显而易见:判断值是否相同。比如下面的例子

如果你想验证LottoId是否等于5,你可以这样做:

使用HasItems

image906×677 37.8 KB

你可以用再次EqualTo(),对WinnerId[0]用一次,对WinnerId[1]用一次。

image992×714 40.4 KB

哈哈,当然不是。你可以使用HasItems,它是这么使用的:

从根开始定位

image1067×701 41.4 KB

额…请教王师傅。

image1080×608 37.8 KB

比如下面的代码,我们可以这么验证:

使用find

image1000×673 34.8 KB

image1024×641 37 KB

答对了,请一定要记住xml和json的区别,不要混谈,那么你能编写一个测试来验证杂货(groceries)的类别是 否包含巧克力(Chocolate)和咖啡(Coffe)吗?

image1051×684 31.5 KB

这确实达到了我的要求,但代码明显有很多bug,如果我更改了category的位置,像下面这样,你的代码就不 适用了,我不难为你了,请王师傅来解答吧:

image1080×688 46.1 KB

find的用法展示的很清楚,不需要我多讲,当然还有一点要注意,你可以这么使用find:

**是个特殊用法,它从xml文档根部开始,进行深度搜索,直到找到符合我们需要的项。

image989×740 44.8 KB

使用findAll

image1047×647 39 KB

现在我手头只有20块钱,我只能买两本书,我更喜欢世纪的谚语和白鲸记,现在的任务是:挑选出格低于10的书籍,并且标题是“世纪的谚语(Sayings of the Century)”和“白鲸记(Moby Dick)”

image1023×666 40.2 KB

对的,这时候应该使用findAll,可以粗鲁的认为多个find的叠加。findAll可以筛选出一批符合要求的数据,而 find只能筛选出一个符合要求的数据,这就像是我们只能挑出一个人领取一等奖,但有很多人可以拿参与奖, 两个方法都有自己的用武之地。

image1080×512 38.1 KB

下面的代码展示了findAll的用法:

提取想要的值

有时候,我们并不想验证是否正确,我们只想取出这个值以进行下一步处理,比如我想取出next的链接:/title?page=2,这种情况怎么办呢?

下面的代码判断内容是不是JSON,并且标题是My Title的话,就返回href链接/title?page=2,这个值被存放在nextTitleLink中,以供我们以后使用。

image880×561 33 KB

image892×470 96.9 KB

当然,有两点需要注意:

  • 返回类型是Response,我们可以用Response.xxx来二次提取想要的值。
  • extract().后面是response()方法,不要写错了。

更改默认值

rest-assured有很多默认值,也正因为如此,需要我们的填的参数可以很少,也可以很多,就像画画一样,可以很精致,也可以很简洁。

image1080×775 55.3 KB

修改端口

rest-assured发起请求时,默认使用的host为localhost,端口为8080,如果你想使用不同的端口,你可以这样做:

或者是这样

或者

修改baseURI和basePath

你也可能改变默认的baseURI、basePath

这就意味着,类似 get("/hello") 这样的一个请求,其实完整的请求为:http://myhost.com:80/resource/hello , 并且使用基础授权认证"username" and “password”。

其他

其他的默认值可以参考下面:

重置

你也可以重置为标准的baseURL(localhost)、basePath(空)、标准端口port(8080)、标准根路径root path(" "),默 认的认证scheme(none)以及URL编码(true),通过下面的方法重置:

specification

在不同的测试用例当中,我们可能会有重复的响应断言或者是请求参数,那么我们可以将重复的这一部分提取出来定义一个规范或者模板,这样的话在后续的测试用例当中就可以使用这个规范模板了。

image1032×1248 81.3 KB

为了达到这个效果,我们可以使用RequestSpecBuilder或 ResponseSpecBuilder来实现,它们之间的区别 是,前者用在请求中,后者则用在body中。

ResponseSpecification重用

例如,你想在多个测试用例中,都使用这样的断言:判断响应状态码是否为200,并且Json数组"x.y"的大小是否 等于2。你可以定义一个ResponseSpecBuilder来实现这个功能:

在这个例子中,需要重用的两个断言数据被定义在"responseSpec",并且与另外一个body断言合并,组成了这个测试用例中全部的断言,那么这个测试用例需要全部断言都通过用例结果才会通过,一旦其中一个断言失败,则测试用例的测试结果为失败。

RequestSpecification重用

同样,假如你想在多个测试用例中重用请求数据,可以通过下面的代码来实现:

这里的请求数据被合并在"requestSpec"中,所以这个请求包含了两个参数(“parameter1"和"parameter2”)以及一 个头部(“header1”)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/56535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端字体压缩(免费简单易上手)

场景:前端在开发过程中有时候要用到特殊字体,但如果引用网上下载好的字体,它们都是一个全的字体文件,这种字体文件里往往包含了大量你用不到的文字字符,从而导致你引入的字体文件大小高达1M以上,这会严重影…

C++08函数模板

1.自动推导类型 在C语言和C98中,auto 关键字用于修饰变量(自动存储的局部变量)。 在C11中,赋予了auto 全新的含义,不再用于修饰的变量,而是作为一个类型指示符,指示编译器在编译时推导auto声明的变量的数据类型。 在…

SpirngBoot<读完包你更上一层楼>

目录 一、SpringBoot概念 1.1 什么是SpringBoot 1.2 为什么要学习SpringBoot 1.3 SpringBoot的特点 1.4 总结 二、入门案例 2.1 创建工程 2.1.1 创建一个空工程 2.1.2 工程名为project_test: 2.1.3 设置jdk版本为1.8 2.1.4 新建一个module 2.1.5 填写项…

入职字节外包一个月,我离职了

有一种打工人的羡慕,叫做“大厂”。 真是年少不知大厂香,错把青春插稻秧。 但是,在深圳有一群比大厂员工更庞大的群体,他们顶着大厂的“名”,做着大厂的工作,还可以享受大厂的伙食,却没有大厂…

[附源码]计算机毕业设计springboot吾悦商城管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

老司机带带你,教你学会Java中又骚又暴力的“反射”技术

在Java中有这么一个很骚的技术,几乎贯穿了所有主流的框架,在所有主流框架的底层中你都可以看见它的身影,这个技术就是反射。关于反射,有很多小白会觉得很难,搞不清楚到底是怎么回事,也不知道该怎么用&#…

VS Code快速实现Git PR操作

注意:建议先学习git的基本操作。 安装插件 下图中红圈标记的插件都安装好。 Fork上游仓库 在网页上点击你想要fork的仓库,点击fork 然后该仓库就会fork到你的github账户下面,如下图。 现在可以在你账户下面的repo(我们称为下…

[附源码]Python计算机毕业设计Django和vue的茶文化交流平台的设计与实现

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

Global Mapper 导出图层功能的妙用(重采样、设置文件类型、切片、按掩膜提取or裁剪……)

许多GIS软件都有导出的功能,但其中大部分的导出功能比较单一直接,仅仅是导出而已,或者最多可以改个导出的格式,改个坐标。但是Global Mapper 不一样,导出功能非常非常多,比如重采样(可以设置重采…

Vue3框架的创建的两种种方案(第十二课)

1 VueCLi脚手架的安装 Home | Vue CLI (vuejs.org) 使用方法 | Yarn 中文文档 (bootcss.com) 3 Vite脚手架的安装 Vite | 下一代的前端工具链 4 使用的软件 Visual Studio Code webstorm64.exe IntelliJ IDEA 2022.2.3 HBuilder X 方案一 VueCLi脚手架的安装 1 创…

[附源码]计算机毕业设计在线招聘网站Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

MobileViT

还是vit系列啊 只不过这次是Apple团队出的轻量级、通用且移动友好的网络框架 论文地址:https://arxiv.org/pdf/2110.02178.pdf 轻量级卷积神经网络 (CNN) 是移动视觉任务的事实。他们的空间归纳偏差使他们能够在不同的视觉任务中以较少的参数学习表示。 轻量级卷积…

微服务自动化【集群搭建】

目录 搭建 etcd 集群 etcd构建自身高可用集群主要有三种形式: 1. 静态部署(前提) 2. 集群搭建 3. 集群测试 搭建 etcd 集群 etcd构建自身高可用集群主要有三种形式: 静态发现:预先已知etcd集群中有哪些节点, 在启动时通过--initial-cluster参数直接指定好etc…

[附源码]JAVA毕业设计互联网保险网站(系统+LW)

[附源码]JAVA毕业设计互联网保险网站(系统LW) 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术&a…

JavaWeb(一)

前言 首先深入了解之前,先回顾一些基础知识 C/S & B/S 就比如咱们日常生活中,咱们说的CF是cs游戏,这个cs是什么意思(年幼的我也十分痴迷CF游戏,过去式了 hhh)这里的cs可不是咱们说的csgo或者cs游戏。…

Vue 官方文档2.x教程学习笔记 1 基础 1.4 模板语法 1.4.1 插值

Vue 官方文档2.x教程学习笔记 文章目录Vue 官方文档2.x教程学习笔记1 基础1.4 模板语法1.4.1 插值1 基础 1.4 模板语法 【介绍】 Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。 所有 Vue.js 的模板都是合法的 HTML&…

Flink SQL管理平台flink-streaming-platform-web安装搭建-整理

目录 步骤 安装 第二步 下载flink 第三步 安装flink-streaming-patform-web 第四步 配置flink web平台 第五步 运行demo 在Flink学习的入门阶段,非常重要的一个过程就是Flink环境搭建,这是认识FLInk框架的第一步,也是为后续的理论学习和…

全栈性能测试教程之性能测试理论(一) mockserver应用

1、mockServer 1.1什么是mockServer moco替代 Server服务 mocoServer即为测试替身的服务 主要针对于单元测试的应用,主要应用于解除单元测试之间的依赖 1.2mocoServer使用的场景 前端程序员 前端已经写好页面,但是后端的接口没有写好&#xff…

[Android]Mac电脑Android Studio使用真机调试运行

一、Mac电脑连接Android真机 我这里是一台中兴手机 1. 手机打开USB调试 打开“设置”找到“关于手机”进入,连续点击版本号,直到提示“您已经进入开发者模式”。回到“设置”找到“系统与更新”进入,再进入“开发者选项”,打开…

Vue笔记_03组件_mavonEditor组件(基于vue)

目录下载mavonEditor导入并注册mavonEditor组件[1] 全局注册[2]局部注册使用mavonEditor属性修改举例说明1-不展示预览分屏工具栏修改举例说明-根据配置显示工具栏编辑器插槽举例说明-自定义工具栏按钮函数监听下载mavonEditor 使用命令 npm install mavon-editor --s 进行下载…