测试开发 | Java 接口自动化测试首选方案:REST Assured 实践

news2024/11/23 9:21:47

在这里插入图片描述

1 . 初识 REST Assured

在 REST Assured 的官方 GitHub 上有这样一句简短的描述: Java DSL for easy testing of REST services 简约的 REST 服务测试 Java DSL

1.1 优点:

REST Assured 官方的 README 第一句话对进行了一个优点的概述,总的意思表达的就是简单好用。那么 REST Assured 有哪些优点,又该如何使用呢?

图片

用 Java 做接口自动化测试首选 REST Assured,具体原因如下:

开源

简约的接口测试 DSL

支持 xml json 的结构化解析

支持 xpath jsonpath gpath 等多种解析方式

对 spring 的支持比较全面

功能很齐全,部分我自己也还没有具体用到,了解到了方向,需要时随时查找学习

2. 如何使用

添加 maven 依赖

<dependency>
   <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>4.0.0</version>
    <scope>test</scope>
</dependency>

2.1 基本三步曲

我们对接口进行测试一般由三步曲:传参、发请求、响应结果断言,REST Assured给我们提供了清晰的三步曲,以given、when、then的结构来实现,基本写法如下:

//使用参数
given().
    param("key1", "value1").
    param("key2", "value2").
when().
    post("/somewhere").
then().
    body(containsString("OK"))

//使用X-Path (XML only) 
given().
    params("firstName", "John", "lastName", "Doe").
when().
    post("/greetMe").
then().
    body(hasXPath("/greeting/firstName[text()='John']"))

2.2 分步拆解

前提:现有一个post请求的登录接口。

http://47.103.xxx.133/auth/oauth/token,

请求体body如下

{
  "password": "elcrD28ZSLLtR0VLs/jERA\u003d\u003d\n",
  "grant_type": "password",
  "scope": "server",
  "userType": 1,
  "username": "xxx"
}

Request Header 如下:

Headers:    Authorization=Basic c3lzdGVtxxxRlbQ==
        Host=47.103.xxx.133
        Accept=*/*
        Content-Type=application/json; charset=ISO-8859-1

分步拆解一

Givern

我们发送请求经常需要带有参数,使用 given() 就可以实现,当时当我们使用 given() 的时候发现其中有很多传参方法如下:

图片

没错,在传参的方法中包含了 param、pathParam、queryParam 和 formParam,下面来研究下这几个传参方法的区别

param

通常我们都会使用 given().param 方法来传参,REST Assured 会根据 HTTP 方法自动尝试确定哪种参数类型(即查询或表单参数),如果是 GET,则查询参数将自动使用,如果使用 POST,则将使用表单参数;

queryParam 和 formParam

有时候在 PUT 或 POST 请求中,需要区分查询参数和表单参数时,就需要使用queryParam 和 formParam 方法了,具体写法如下:

given().
       formParam("formParamName", "value1").
       queryParam("queryParamName", "value2").
when().
       post("/something")

pathParam

使用given时指定请求路径的参数,这个方法很少用到,或者说我本人几乎没用到过(可能我的修行还不够,踩坑还太少~);具体写法如下:

given().
        pathParam("OAuth", "oauth").
        pathParam("accessToken", "token").
when(). 
        post("/auth/{OAuth}/{accessToken}").
then().
         ..

header/headers

经常还需要在请求头中带入参数,这个时候就可以使用header或headers方法,写法如下:

given()
       .header("Authorization","Basic c3lzdGVtOxxxbQ==")
       .header("Host","47.xxx.xxx.133")

或者用headers将多个参数写在一起:

given()
       .headers("Authorization","Basic c3lzdGVtxxx3RlbQ==","Host","47.xxx.xxx.133")

cookie

有时候需要在请求中带入cookie,restassured提供了cookie方法来实现:

given()
      .cookie("c_a","aaaaaa")
      .cookie("c_b","bbbbbb"). ..

contentType

经常还会设置contentType,最常见的就是application/json了,写法如下:

given().contentType("application/json"). ..
//或者
given().contentType(ContentType.JSON). ..

body

在POST, PUT 或 DELETE请求中,我们经常还需要带上请求体body,写法如下:

given().body("{\n" +
                "\t\"password\": \"elcrD28xxxR0VLs/jERA\\u003d\\u003d\\n\",\n" +
                "\t\"grant_type\": \"password\",\n" +
                "\t\"scope\": \"server\",\n" +
                "\t\"userType\": 1,\n" +
                "\t\"username\": \"xxx\"\n" +
                "}")

也可以用request更为明确的指出是请求body:

given().request().body("{\n" +
                "\t\"password\": \"elcrD28xxxR0VLs/jERA\\u003d\\u003d\\n\",\n" +
                "\t\"grant_type\": \"password\",\n" +
                "\t\"scope\": \"server\",\n" +
                "\t\"userType\": 1,\n" +
                "\t\"username\": \"xxx\"\n" +
                "}")

没有参数

如果我们没有参数需要传递,也可以省略掉given():

get("/lotto").then().assertThat().body("lotto.lottoId", equalTo(5));

proxy

有时候我们需要进行接口的调试,抓包是最常用的一种方式,rest-assured 提供了 proxy 方法,可以设置代理,写法如下:

given().proxy("127.0.0.1",8888). ..

实际运行结果:

在这里插入图片描述

在这里插入图片描述

分步拆解二

When

when主要用来触发请求,在when后面接着请求URL:

given().when().post("http://47.103.xxx.133/auth/oauth/token"). ..

前面在 given 中我们设置了很多请求参数,在 when 中也可以设置,只不过要注意的是在请求之前设置;这也比较好理解,如果再请求之后的话,参数都设置怎么发请求呢?

  given()
    .when()
        .contentType(ContentType.JSON)
        .headers("Authorization","Basic c3lzxxx3RlbQ==","Host","47.xxx.xxx.133")
        .request().body("{\n" +
            "\t\"password\": \"elcrD28ZSLLtR0VLs/jERA\\u003d\\u003d\\n\",\n" +
            "\t\"grant_type\": \"password\",\n" +
            "\t\"scope\": \"server\",\n" +
            "\t\"userType\": 1,\n" +
            "\t\"username\": \"qinzhen\"\n" +
            "}")
        .post("http://47.xxx.xxx.133/auth/oauth/token")
     . ..

分步拆解三

Then

then后面可以跟断言,也可以获取响应值

断言-then().body()

then().body() 可以对响应结果进行断言,在 body 中写入断言:

.. post("http://47.xxx.xxx.133/auth/oauth/token")
   .then().statusCode(200).body("code",equalTo(1));

其中statusCode(200)是对状态码的断言,判断状态码是否为200; body(“code”,equalTo(1))是对返回体中的 code 进行断言,要求返回 code值为1 。

注:这里的equalTo使用的是hamcrest断言,不了解的小伙伴可参考另外一篇文章:Junit原生断言和hamcrest断言的区别及使用

实操演示:

我们将上述的 given、when、then 结合起来看一下实际运行效果,这里在运行之前再提一个功能,我们可以在 when 和 then 后面加上.log().all(),这样在运行过程中就可以把请求和响应的信息都打印出来:

在这里插入图片描述

在这里插入图片描述

获取响应-then().extract().body().path(“code”)

我们可以在 then 后面利用 .extract().body() 来获取我们想要 body 的返回值,它们也可以直接接在断言后面,写法如下:

注意这里的body() 不要和请求体body()以及断言的body()混淆了

.. .then()
        .log().all().statusCode(200).body("code",equalTo(1))
        .extract().body().path("code");

实操演示:

演示前再来看一个新的功能,上面我们再写请求体 body 时时这样的:

body("{\n" +
    "\t\"password\": \"elcrD28ZxxxVLs/jERA\\u003d\\u003d\\n\",\n" +
    "\t\"grant_type\": \"password\",\n" +
    "\t\"scope\": \"server\",\n" +
    "\t\"userType\": 1,\n" +
    "\t\"username\": \"qinzhen\"\n" +
    "}")

看起来有点丑,改造一下;rest-assured 为我们提供了一个利用 HashMap 来创建json 文件的方法,先把要传的字段放入 hashmap 中,然后用 contentType 指明JSON 就可以了,具体写法如下:

HashMap map = new HashMap();
map.put("password","elcrD28ZSLLtR0VLs/jERA\u003d\u003d\n");
map.put("grant_type","password");
map.put("scope","server");
map.put("userType",1);
map.put("username","xxx");
given()
      .headers("Authorization","Basic c3lzdGVtxxxlbQ==","Host","47.xxx.xxx.133")
      .contentType(JSON)
      .body(map). ..

现在进行完整的请求,获取返回值 code 并打印:

HashMap map = new HashMap();
map.put("password","elcrD28ZSLLtR0VLs/jERA\u003d\u003d\n");
map.put("grant_type","password");
map.put("scope","server");
map.put("userType",1);
map.put("username","xxx");
Integer code = 
given()
    .headers("Authorization","Basic c3lzdGVtxxxlbQ==","Host","47.xxx.xxx.133")
    .contentType(JSON)
    .body(map).
when()
    .log().all().post("http://47.xxx.xxx.133/auth/oauth/token").
then()
    .log().all().statusCode(200).body("code",equalTo(1))
    .extract().body().path("code");
System.out.println("返回code的值是:"+code);

运行结果:

图片

推荐学习

关于REST Assured,这里仅仅算是初步认识。认识它的语法结构和功能,对于更多丰富的用法还需要慢慢探索研究,特别是断言的部分,是测试工程师最常用最终要的功能之一。REST Assured提供的完整断言手段,在后续文章中我们一起探讨。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

在这里插入图片描述

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!   

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

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

相关文章

如何把Word转换成PDF文档?分享操作简单的方法

在人们办公过程中&#xff0c;word、excel以及pdf这三种格式的文件经常会被使用到。这三类文件因为格式不同&#xff0c;使用时理论上应该是各管各的&#xff0c;但是实际使用时却时不时会遇到要对它们三者进行格式转换的情况。那么&#xff0c;如何把Word转换成PDF文档呢?接下…

通过IP地址进行精准定位技术、方法与隐私问题的探讨

导语&#xff1a;随着互联网和移动设备的普及&#xff0c;通过IP地址进行精准定位已成为现实。这一技术的发展带来了许多便利&#xff0c;但也引发了隐私问题的关注。本文将探讨通过IP地址进行精准定位的技术、方法以及涉及的隐私问题。 技术和方法&#xff1a; IP地址的基…

荧光量子产率测试用的是什么积分球

LED(Light-EmittingDiode)作为一种新型的固态光源&#xff0c;以其绿色环保、寿命超长、高效节能等特点成为继白炽灯、荧光灯和高压气体放电灯之后的第四代照明光源。 蓝光LED芯片和钇铝石榴石&#xff08;YAG&#xff09;荧光粉封装在一起得到白光LED的方法具有结构简单、制作…

线程池|单例模式|STL、智能指针线程安全|读者写者问题

线程池 线程池的逻辑思想&#xff1a; 每当我们处理一个任务就要创建一个线程&#xff0c;创建线程的开销是很大的。因此我们可以预先创建一批线程&#xff0c;任务队列里没有任务的时候&#xff0c;每个线程都休眠&#xff0c;当队里中有任务的时候&#xff0c;就可以唤醒线程…

牵手时代少年团,来伊份讲了一个“新鲜”故事

从数天前来伊份官方发布一组悬念九宫图海报开始&#xff0c;其新代言人的身份就呼之欲出。 9月7日上午9点&#xff0c;来伊份正式宣布时代少年团为全新品牌代言人。这一官宣在微博引爆并引发了轰动效应&#xff0c;同时代言人同款IP礼盒“伊份心选”正式发售。 图源&#xff1…

马拉松成绩训练利器“亚索800”

在马拉松火热的今天&#xff0c;跑圈中流行着各种各样的马拉松训练方法 其实在众多的流派体系中基本可归纳为两类&#xff1a; 1、强调基础有氧训练&#xff0c;以中低强度长时间跑步训练为主&#xff0c;LSD、MAF180、细胞分裂法都归属于这类训练&#xff1b; 2、强调高强度间…

大数据技术之Hadoop:Yarn集群部署(七)

目录 一、部署说明 二、集群规划 三、开始配置 3.1 MapReduce配置文件 3.2 YARN配置文件 3.3 分发配置文件 四、集群启停 4.1 命令介绍 4.2 演示 4.3 查看YARN的WEB UI页面 一、部署说明 Hadoop HDFS分布式文件系统&#xff0c;我们会启动&#xff1a; NameNode进…

帆软报表简单设置分组汇总

前言 接手之前同事留下的一个胶膜产品入库登记表&#xff08;帆软报表&#xff09;&#xff0c;结果手滑把原来的报表行删除了。用户反馈需要恢复按报表中 “型号” “卷数” 分组汇总一下 “件数” 字段的值、也就是按每种同型号同卷数分组、相同分组的要有一行汇总&#xf…

将 Qt Designer 的 ui 文件转换为 PySide2 使用的.py 文件

20201206 修订&#xff1a;在 Pyside2 的 5.15.2 版本中&#xff0c;从 ui 生成 py 文件过程&#xff0c;命令从 “uic” 变为 “pyside2-uic” Qt Designer 设计的 ui 文件&#xff0c;就是一个 xml 文件&#xff0c;通过 pyside-uic 可以转换成标准的.py 文件 。通过 QtDesi…

阿里云App备案详细流程_APP备案问题解答

阿里云APP备案流程分为6步&#xff0c;APP备案成功后应用可以上架&#xff0c;登录阿里云账号填写APP信息&#xff0c;等待阿里云初审&#xff0c;初审通过后进行工信部短信核验&#xff0c;管局审核通过后APP即可备案成功&#xff0c;最后移动APP应用可以分发平台上架&#xf…

习题练习 C语言(暑期第四弹)

自我小提升&#xff01; 前言一、数组二、指针运算三、统计每个月兔子的总数四、双指针的应用五、判断指针六、珠玑妙算七、两数之和八、数组下标九、指针十、寻找峰值十一、二级指针十二、大端小端十三、无符号参数十四、数对十五、截取字符串总结 前言 重要的事说三遍&#…

【校招VIP】JAVA语言考点之多线程实现相关

考点介绍&#xff1a; 多线程是JAVA校招中出现频度比较高的考点&#xff0c;本专题需要熟悉四种多线程的实现方式&#xff0c;并深入对比和区别。另外&#xff0c;对线程的状态和变化的相关题型也进行了分析。 JAVA语言考点之多线程实现相关-相关题目及解析内容可点击文章末尾…

CSS:实现文字溢出显示省略号且悬浮显示tooltip完整信息

组件&#xff1a; element ui中的tooltip组件 思路&#xff1a;通过ref获取宽度进行判断&#xff0c;当子级宽度大于对应标签/父级宽度显示tooltip组件 <div class"bechmark-wrap"><ul ref"bechmarkUl"><liv-for"(item,index) in comp…

SVN 索引版本与打包版本号不匹配

今天突然遇到了一个问题&#xff0c;SVN上传不了&#xff0c;错误提示如下&#xff1a; 解决方法&#xff1a; 1.其实&#xff0c;这是SVN库不小心搞坏了&#xff0c;只能重新再创建一个SVN仓库了。

Java jvm 内存溢出分析

1.如何分析jvm内存溢出呢 我们经常用visualVm监控Jvm的内存&#xff0c;cpu&#xff0c;线程的使用情况&#xff0c;通常可以根据内存不断增长来判断内存是否存在不释放。但是我们不可能时时盯着去看&#xff0c;这里涉及jvm堆内存配置&#xff0c;堆内存参数配置和调优会在其…

mongodb数据库操作

1、启动mongodb /usr/local/mongodb/bin/mongod --dbpath /var/mongodb/data/--logpath /var/mongodb/logs/log.log &在mongodb启动命令中 --dbpath 指定mongodb的数据存储路径 --logpath 指定mongodb的日志存储路径 2、停止mongodb 第一步先进入mongo命令行模式 第二…

nvm管理多个版本的nodejs

1. 已经安装过nodejs在安装nvm的步骤 1.安装nvmhttps://github.com/coreybutler/nvm-windows/releases 2.nvm安装位置 2.nvm管理的nodejs安装位置 4.最终的安装结构 备注&#xff1a;nodejs安装 2.使用nvm安装管理nodejs 2.1配置下载镜像&#xff1a; 找到nvm安装路径…

sonarqube版本升级

官方文档&#xff1a;Upgrade guide 步骤1、停止原有sonarqube服务&#xff0c;如果是docker部署的直接停掉容器并删除 步骤2、部署最新版sonarqube&#xff0c;保留原有配置 步骤3、访问sonarqube web 显示维护中&#xff0c;根据官方给出的升级方法&#xff0c;在sonarqub…

如何从公司或学校远程访问家里的电脑?

在某些情况下&#xff0c;我们需要远程访问另一台电脑&#xff0c;如在公司访问家里电脑的文件。那么&#xff0c;如何才能从公司或学校远程访问家里的电脑呢&#xff1f;这就需要用到远程访问软件了。 什么是远程访问软件&#xff1f; 远程访问软件是一种允许从本地电脑远…

python基础教程: while 循环语句用法

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 话不多说&#xff0c;直接开搞&#xff0c;如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 一.while 循环结构 特征: 减少代码冗余,提升代码效率 语法: while 条件表达式:code1code2...1.初始化一个变量 2.写上…