rest-assured请求实践及响应获取

2022/4/28 6:15:40

本文主要是介绍rest-assured请求实践及响应获取,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

  REST Assured是一个可以简化HTTP Builder顶层 基于REST服务的测试过程的Java DSL(针对某一领域,具有受限表达性的一种计算机程序设计语言)。它支持发起POST,GET,PUT,DELETE,OPTIONS,PATCH和HEAD请求,并且可以用来验证和校对这些请求的响应信息。它的语法非常简洁,是一种专为测试 REST API 而设计的测试框架。


文档

官方文档:

https://github.com/rest-assured/rest-assured/wiki/Usage

中文手册:

https://github.com/RookieTester/rest-assured-doc/blob/master/2016-12-12-【接口测试】rest-assured用户手册中文版.markdown


基本使用

1.Maven的pom.xml添加 REST-Assured 依赖坐标

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

maven地址:

https://mvnrepository.com/artifact/io.rest-assured/rest-assured

2.语法格式

given().
   XXXX
when().
   XXXX
then().
   XXXX

类似于行为驱动开发(Behaviour Driven Development-BDD)中的定义的结构 Given-When-Then,Given:
在某场景下,When:发生什么事件,Then:产生了什么结果。而 REST-Assured 借鉴了这一套描述可以使
得语法更加简洁:

  • given 设置测试预设(包括请求头、请求参数、请求体、cookies 等等)
  • when 所要执行的操作(GET/POST 请求)
  • then 解析结果、断言

get请求

1、参数拼接在URL地址后面

@Test(description = "get请求,参数拼接在url后面")
public void getRequest() {
	given().
			// 设置请求:请求头,请求体等
	when().
			get("http://www.httpbin.org/get?phone=13888888888&pwd=123456").
	then().
			log().body();
}

响应:

{
    "args": {
        "phone": "13888888888",
        "pwd": "123456"
    },
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Host": "www.httpbin.org",
        "User-Agent": "Apache-HttpClient/4.5.3 (Java/1.8.0_211)",
        "X-Amzn-Trace-Id": "Root=1-626949ef-6009da1921b20b3b56bc20ad"
    },
    "origin": "112.21.34.139",
    "url": "http://www.httpbin.org/get?phone=13888888888&pwd=123456"
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

2、通过queryParam方法添加参数

@Test(description = "get请求,通过queryParam传入参数")
public void getRequest() {
	given().
			queryParam("phone", "13888888888").
			queryParam("pwd", "123456").
	when().
			get("http://www.httpbin.org/get").
	then().
			log().body();
}

响应:

{
    "args": {
        "phone": "13888888888",
        "pwd": "123456"
    },
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Host": "www.httpbin.org",
        "User-Agent": "Apache-HttpClient/4.5.3 (Java/1.8.0_211)",
        "X-Amzn-Trace-Id": "Root=1-62694a56-1d9db03434d76e9654b13284"
    },
    "origin": "112.21.34.139",
    "url": "http://www.httpbin.org/get?phone=13888888888&pwd=123456"
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

post请求

1、form表单参数类型

@Test(description = " form表单参数类型")
public void postFormRequest() {
	given().
			formParam("phone", "13888888888").
			formParam("pwd", "123456").
			contentType("application/x-www-form-urlencoded").
	when().
			post("http://www.httpbin.org/post").
	then().
			log().body();
}

如果使用formParam()方法的话,可以不用加上contentType,框架会自动添加。

响应:

{
    "args": {
        
    },
    "data": "",
    "files": {
        
    },
    "form": {
        "phone": "13888888888",
        "pwd": "123456"
    },
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Content-Length": "28",
        "Content-Type": "application/x-www-form-urlencoded; charset=ISO-8859-1",
        "Host": "www.httpbin.org",
        "User-Agent": "Apache-HttpClient/4.5.3 (Java/1.8.0_211)",
        "X-Amzn-Trace-Id": "Root=1-62694c17-21f67614068e25ee25b95a33"
    },
    "json": null,
    "origin": "112.21.34.139",
    "url": "http://www.httpbin.org/post"
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

2、json参数类型

@Test(description = " json参数类型")
public void postJsonRequest() {
	String requestBody = "{\n" +
			"\t\"phone\": \"13888888888\",\n" +
			"\t\"pwd\": \"123456\"\n" +
			"}";
	given().
			body(requestBody).
			contentType(ContentType.JSON).
	when().
			post("http://www.httpbin.org/post").
	then().
			log().body();
}

响应:

{
    "args": {
        
    },
    "data": "{\n\t\"phone\": \"13888888888\",\n\t\"pwd\": \"123456\"\n}",
    "files": {
        
    },
    "form": {
        
    },
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Content-Length": "45",
        "Content-Type": "application/json; charset=UTF-8",
        "Host": "www.httpbin.org",
        "User-Agent": "Apache-HttpClient/4.5.3 (Java/1.8.0_211)",
        "X-Amzn-Trace-Id": "Root=1-62694de7-5a9ff83b4d2ece035f62f5b7"
    },
    "json": {
        "phone": "13888888888",
        "pwd": "123456"
    },
    "origin": "112.21.34.139",
    "url": "http://www.httpbin.org/post"
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

3、xml参数类型

@Test(description = " xml参数类型")
public void postXmlRequest() {
	String xmlData = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
			"<listeners>\n" +
			"    <listener class-name=\"com.boge.listener.TestFailListener\"></listener>\n" +
			"</listeners>";
	given().
			body(xmlData).
			contentType(ContentType.XML).
	when().
			post("http://www.httpbin.org/post").
	then().
			log().body();
}

响应:

{
    "args": {
        
    },
    "data": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<listeners>\n    <listener class-name=\"com.boge.listener.TestFailListener\"></listener>\n</listeners>",
    "files": {
        
    },
    "form": {
        
    },
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Content-Length": "138",
        "Content-Type": "application/xml; charset=ISO-8859-1",
        "Host": "www.httpbin.org",
        "User-Agent": "Apache-HttpClient/4.5.3 (Java/1.8.0_211)",
        "X-Amzn-Trace-Id": "Root=1-6269505a-20c8451a0c3d627b7b14957b"
    },
    "json": null,
    "origin": "112.21.34.139",
    "url": "http://www.httpbin.org/post"
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

4、上传文件

我们传送大容量的数据到服务端时,我们通常使用 multipart 表单数据技术。rest-assured提供了一个叫做
multiPart 的方法可以让我们指定文件(file)、字节数组(byte-array)、输入流或者是上传文件

@Test(description = " 文件上传类型")
public void postFileRequest() {
	given().
			multiPart(new File("E:\\Notes\\1.png")).
	when().
			post("http://www.httpbin.org/post").
	then().
			log().body();
}

响应:

{
    "args": {
        
    },
    "data": "",
    "files": {
        "file": "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAABKgAAAFcCAYAAADs5oaNAAAgAElEQVR4AezdC3hUVZ7v/S8ZdnOS4akcHkrfClo4JtgJTbAJ0yGvhjb"
    },
    "form": {
        
    },
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Content-Length": "62999",
        "Content-Type": "multipart/form-data; boundary=Ud7BcBwbkM3RSzh0JevpiOKUjKC5O38NN",
        "Host": "www.httpbin.org",
        "User-Agent": "Apache-HttpClient/4.5.3 (Java/1.8.0_211)",
        "X-Amzn-Trace-Id": "Root=1-62695230-7998092d01ddb50515e7d340"
    },
    "json": null,
    "origin": "112.21.34.139",
    "url": "http://www.httpbin.org/post"
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

获取响应信息

1、extract().response()

@Test
public void getResponse() {
	Response response = given().
			when().
				post("http://www.httpbin.org/post").
			then().
				log().all().extract().response();
}

响应:

HTTP/1.1 200 OK
Date: Wed, 27 Apr 2022 14:47:29 GMT
Content-Type: application/json
Content-Length: 501
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
    "args": {
        
    },
    "data": "",
    "files": {
        
    },
    "form": {
        
    },
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Content-Length": "0",
        "Content-Type": "application/x-www-form-urlencoded; charset=ISO-8859-1",
        "Host": "www.httpbin.org",
        "User-Agent": "Apache-HttpClient/4.5.3 (Java/1.8.0_211)",
        "X-Amzn-Trace-Id": "Root=1-62695781-54a196cc23ac032140a2a1e3"
    },
    "json": null,
    "origin": "112.21.34.139",
    "url": "http://www.httpbin.org/post"
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

2、Gpath响应体数据提取

官网对Gpath的说明

GPath is a path expression language integrated into Groovy which allows parts of nested structured

data to be identified. In this sense, it has similar aims and scope as XPath does for XML. The two

main places where you use GPath expressions is when dealing with nested POJOs or when dealing

with XML

简单来说 GPath 是一种路径表达式语言,类似于 xpath,GPath 不仅可以应用于 XML,还可以应用于
JSON、HTML。

提取json

代码:

@Test
public void getResponse() {
	Response response = given().
						when().
							get("http://www.httpbin.org/json").
						then().
							log().all().extract().response();
}

响应:

HTTP/1.1 200 OK
Date: Wed, 27 Apr 2022 15:20:54 GMT
Content-Type: application/json
Content-Length: 429
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
    "slideshow": {
        "author": "Yours Truly",
        "date": "date of publication",
        "slides": [
            {
                "title": "Wake up to WonderWidgets!",
                "type": "all"
            },
            {
                "items": [
                    "Why <em>WonderWidgets</em> are great",
                    "Who <em>buys</em> WonderWidgets"
                ],
                "title": "Overview",
                "type": "all"
            }
        ],
        "title": "Sample Slide Show"
    }
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

获取响应数据里的具体值:

// 获取author
logger.info(response.jsonPath().get("slideshow.author"));
// 获取slides里的第一个title
logger.info(response.jsonPath().get("slideshow.slides.title[0]"));
// 获取slides里的第二个title
logger.info(response.jsonPath().get("slideshow.slides.title[1]"));
// 获取slides里的所有title
List<String>  titleList = response.jsonPath().get("slideshow.slides.title");
for (String title: titleList) {
	logger.info("title is:" + title);
}

具体打印结果:

[2022-04-27 23:44:15] [INFO ] [RestAssuredDemo:110] - Yours Truly
[2022-04-27 23:44:15] [INFO ] [RestAssuredDemo:112] - Wake up to WonderWidgets!
[2022-04-27 23:44:15] [INFO ] [RestAssuredDemo:114] - Overview
[2022-04-27 23:44:15] [INFO ] [RestAssuredDemo:118] - title is:Wake up to WonderWidgets!
[2022-04-27 23:44:15] [INFO ] [RestAssuredDemo:118] - title is:Overview

提取html

代码:

@Test
public void getResponseHtml() {
	Response response = given().
				when().
						get("https://www.baidu.com").
				then().
						log().all().extract().response();
}

响应:

HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 1145
Content-Type: text/html
Server: bfe
Date: Wed, 27 Apr 2022 15:51:50 GMT

<html>
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
    <meta name="referrer" content="always"/>
    <link rel="stylesheet" type="text/css" href="https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css"/>
    <title>百度一下,你就知道</title>
  </head>
  <body link="#0000cc">
    <div id="wrapper">
      <div id="head">
        <div class="head_wrapper">
          <div class="s_form">
            <div class="s_form_wrapper">
              <div id="lg">
                <img hidefocus="true" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129"/>
              </div>
              <form enctype="application/x-www-form-urlencoded" method="get" class="fm" id="form" name="f" action="//www.baidu.com/s">
                <input type="hidden" name="bdorz_come" value="1"/>
                <input type="hidden" name="ie" value="utf-8"/>
                <input type="hidden" name="f" value="8"/>
                <input type="hidden" name="rsv_bp" value="1"/>
                <input type="hidden" name="rsv_idx" value="1"/>
                <input type="hidden" name="tn" value="baidu"/>
                <span class="bg s_ipt_wr">
                  <input maxlength="255" type="text" class="s_ipt" id="kw" name="wd" value="value" autocomplete="off" autofocus="autofocus"/>
                </span>
                <span class="bg s_btn_wr">
                  <input type="submit" class="bg s_btn" id="su" value="百度一下" autofocus="autofocus"/>
                </span>
              </form>
            </div>
          </div>
          <div id="u1">
            <a shape="rect" class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>
            <a shape="rect" class="mnav" href="https://www.hao123.com" name="tj_trhao123">hao123</a>
            <a shape="rect" class="mnav" href="http://map.baidu.com" name="tj_trmap">地图</a>
            <a shape="rect" class="mnav" href="http://v.baidu.com" name="tj_trvideo">视频</a>
            <a shape="rect" class="mnav" href="http://tieba.baidu.com" name="tj_trtieba">贴吧</a>
            <noscript>
              <a shape="rect" class="lb" href="http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login">登录</a>
            </noscript>
            <script>document.write('&lt;a href="http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&amp;")+ "bdorz_come=1")+ '" name="tj_login" class="lb"&gt;登录&lt;/a&gt;');
                </script>
            <a shape="rect" class="bri" href="//www.baidu.com/more/" name="tj_briicon" style="display: block;">更多产品</a>
          </div>
        </div>
      </div>
      <div id="ftCon">
        <div id="ftConw">
          <p id="lh">
            <a shape="rect" href="http://home.baidu.com">关于百度</a>
            <a shape="rect" href="http://ir.baidu.com">About Baidu</a>
          </p>
          <p id="cp">
©2017 Baidu             <a shape="rect" href="http://www.baidu.com/duty/">使用百度前必读</a>
              <a shape="rect" class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a>
 京ICP证030173号              <img src="//www.baidu.com/img/gs.gif"/>
          </p>
        </div>
      </div>
    </div>
  </body>
</html>

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

获取响应数据的具体值:

// 获取head下的title, 文本信息
logger.info(response.htmlPath().get("html.head.title"));
// 获取head下的meta, 属性信息
logger.info(response.htmlPath().get("html.head.meta[0].@content"));

具体打印结果:

[2022-04-27 23:58:40] [INFO ] [RestAssuredDemo:130] - 百度一下,你就知道
[2022-04-27 23:58:40] [INFO ] [RestAssuredDemo:132] - text/html;charset=utf-8

提取xml

代码:

@Test
public void getResponseXml() {
	Response response = given().
				when().
						get("http://www.httpbin.org/xml").
				then().
						log().all().extract().response();
}

响应:

HTTP/1.1 200 OK
Date: Wed, 27 Apr 2022 16:10:18 GMT
Content-Type: application/xml
Content-Length: 522
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

<?xml version='1.0' encoding='us-ascii'?>
<!--  A SAMPLE set of slides  -->
<slideshow 
    title="Sample Slide Show"
    date="Date of publication"
    author="Yours Truly"
    >
    <!-- TITLE SLIDE -->
    <slide type="all">
        <title>Wake up to WonderWidgets!</title>
    </slide>
    <!-- OVERVIEW -->
    <slide type="all">
        <title>Overview</title>
        <item>Why 
            <em>WonderWidgets</em> are great
        </item>
        <item/>
        <item>Who 
            <em>buys</em> WonderWidgets
        </item>
    </slide>
</slideshow>

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

获取响应数据的具体值:

// 获取第二个slide下的title, 文本信息
logger.info(response.xmlPath().get("slideshow.slide[1].title"));
// 获取第二个slide的type属性, 属性信息
logger.info(response.xmlPath().get("slideshow.slide[1].@type"));

具体打印结果:

[2022-04-28 00:17:01] [INFO ] [RestAssuredDemo:143] - Overview
[2022-04-28 00:17:01] [INFO ] [RestAssuredDemo:145] - all


这篇关于rest-assured请求实践及响应获取的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程