rest-assured入门

1. rest-assured依赖、结构

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>5.5.0</version>
    <scope>test</scope>
</dependency>
given() 
    //可以设置测试预设(包括header、cookie、请求参数、请求体) 
.when() 
    //所要执行的操作(请求方法)
.then()
    //请求结束之后的操作(解析响应结果、断言)

 

2. 请求类型

请求方式 ContentType请求体类型 java示例-rest-assured
get 无参/有参 
@Test
public void fun() {
    given()
        //方式1:使用param或queryParam配置参数
        .param("username", "Hogwarts")
        .queryParam("key","abcdefg")
        //queryParam是为post提供的参数,但做了兼容,不会报错
        .log().params() //打印参数
    .when()
        //方式2:URL拼接参数
        .get("https://httpbin.org/get?pwd=123456")
    .then()
        .statusCode(200);
}
post application/x-www-form-urlencode
在发送前编码所有字符,只能上传 键值对
Http默认提交数据的方式
@Test
public void fun2(){
    given()
        .param("hello","world")
        .log().all() //打印完整请求信息
    .when()
        .post("https://httpbin.org/post")
    .then()
        .log().all() //打印完整响应信息
        .statusCode(200);//响应断言
}
multipart/form-data
不对字符编码。
在使用包含文件上传空间的表单时,必须使用该值
@Test
public void testFormData(){
    HashMap<String,String> params = new HashMap<>();
    params.put("username","张三");
    params.put("password","123456");
    given()
        .contentType("application/x-www-form-urlencoded;charset=utf-8")
        //1. 单个参数
        .formParam("课程","Java")
        //2. 通过HashMap存放
        .formParams(params)
        //3. 通过字符串存放
        .formParams("username","王五","pwd","abcdef")
    .when()
        .post("https://httpbin.org/post")
    .then()
        .log().all()
    .statusCode(200);
}
application/json
请求主体是序列化的json字符串
@Test
public void getToken(){
    String url = "https://httpbin.org/post";
    //方式1:传入json字符串
    given()
        .body("{\"username\":\"13687300222\", \"password\":\"123456\"}")
        .post(url)
        .prettyPeek();

    //方式2:传入HashMap对象。
    //需要导入jackson,否则会提示序列化错误
    //groupId: com.fasterxml.jackson.core
    //artifactId: jackson-databind
    HashMap<String,String> jsonobj = new HashMap<>();
    jsonobj.put( "hello","tom");
    given()
        .contentType("application/json")
        .body(jsonobj)
    .when()
        .post("https://httpbin.ceshiren.com/post")
    .then().log().all();
}
text/xml
请求主题是xml文件

xml接口地址

<!-- add.xml文件内容 -->
<Envelope  xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <Add xmlns="http://tempuri.org/">
            <intA>8</intA>
            <intB>9</intB>
        </Add>
    </Body>
</Envelope>

测试代码

 

@Test
public void testXML(){
    try {
        FileInputStream fip = new FileInputStream("src/main/resources/add.xml");
        //导入依赖,将输入流转化为字符串
        //groupId: commons-io artifactId: commons-io
        String reqbody = IOUtils.toString(fip,"UTF-8");
        given()
            .contentType("text/xml")
            .body(reqbody)
            .log().headers()
            .log().body()
        .when()
            .post("http://dneonline.com/calculator.asmx")
        .then()
            .body("//AddResult.text()",equalTo("17"))
            .log().all().statusCode(200);
    }catch (FileNotFoundException e){
        System.out.println("文件不存在");
    }catch (IOException e){
        System.out.println("文件转码失败");
    }
}
put  
@Test
public void testPut(){
    given()
        //要求服务器返回json类型
        .header("accept","application/json")
        .body("\"cat\":\"tom\"")
    .when()
        .put("https://httpbin.org/put")
    .then()
        .log().all()
        .statusCode(200);
}
delete    
@Test
public void testDelete(){
    given()
        .contentType("application/json")
        .body("{\"shopId\":\"11365498\"}")
    .when()
        .delete("https://httpbin.org/delete")
    .then()
        .log().all()
        .statusCode(200);
}

 

 

3. 解析相应

3.1 简单断言

类型 断言方法 含义 示例
状态码 statsCode() 响应状态码
1xx 消息服务端已接收到请求,需要继续处理
2xx 请求已成功被服务器接收、理解、并接受
3xx 重定向
4xx 请求错误
5xx/6xx 服务器错误
@Test
public  void testStatusCode(){
    given()
    .when()
        .get("https://httpbin.org/get")
    .then()
        .log().all()
        .header("Content-Type",equalTo("application/json"))
        .body("origin",containsString("111.18.134.11"))
        .statusCode(200);
}
响应头 header() 响应头信息
内容 body() 内容完全匹配

3.2 xml

xpath语法

/   根节点
.   现行节点
//  不管位置,选择所有符合条件的元素
*   匹配所有元素节点
[]  迭代器标示
|   支持迭代器中做多选

 

<!-- 请求的xml文件 -->
<Envelope  xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <Add xmlns="http://tempuri.org/">
            <intA>8</intA>
            <intB>9</intB>
        </Add>
    </Body>
</Envelope>
/* 测试代码*/
@Test
public void testXML(){
    try {
        FileInputStream fip = 
            new FileInputStream("src/main/resources/add.xml");
        String reqbody = IOUtils.toString(fip,"UTF-8");
        given()
            .contentType("text/xml")
            .body(reqbody)
            .log().headers()
            .log().body()
        .when()
            .post("http://dneonline.com/calculator.asmx")
        .then()
            .body("//AddResult.text()",equalTo("17"))
            .log().all().statusCode(200);
    }catch (FileNotFoundException e){
        System.out.println("文件不存在");
    }catch (IOException e){
        System.out.println("文件转码失败");
    }
}
<!-- 响应结果 -->
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <AddResponse xmlns="http://tempuri.org/">
      <AddResult>17</AddResult>
    </AddResponse>
  </soap:Body>
</soap:Envelope>

3.3 json

 

JSONPath练习

$   根节点
@   现行节点
..  不管位置,选择所有符合条件的元素
*   匹配所有元素节点
.   取子节点
[]  取子节点,支持名称或者下标
[,]     支持迭代器中做多选
?()     支持过滤操作

练习用的json数据

{
    "firstName": "John",
    "lastName": "doe",
    "age": 26,
    "address": {
        "streetAddress": "naist street",
        "city": "Nara",
        "postalCode": "630-0192"
    },
    "phoneNumbers": [
        {
            "type": "iPhone",
            "number": "0123-4567-8888"
        },
        {
            "type": "home",
            "number": "0123-4567-8910"
        }
    ]
}
  • 使用.
    • $.address.city
    • $.phoneNumbers[0].number
    • $.phoneNumbers[*].number
    • $..number
  • 使用[]
    • $[address][city]
    • $[phoneNumbers][0][number]
  • 过滤条件
    • $.phoneNumbers[?(@.type == 'iPhone')].number

使用rest-assured内嵌工具解析

@Test
public void testJsonParse(){
    Response res = given()
        .header("Hello","tom")
    .when()
        .get("https://httpbin.org/get")
    .then()
        .log().all()
        .statusCode(200)
        .extract().response();
    //toString返回对象
    String ts = res.toString();
    //asStrubg返回字符串
    String as= res.asString();
    String word = from(as)
        .getString("headers.Hello");
    assertEquals("tom",word);
}

使用三方解析

/*
* groupId: com.jayway.jsonpath
* artifactId: json-path
*/
@Test
public void testJsonPath3rd(){
    String res = given()
        .header("Hello","tom")
    .when()
        .get("https://httpbin.org/get")
    .then()
        .log().all()
        .statusCode(200)
        //提取响应文本
        .extract().response().asString();
    String word = JsonPath
        .read(res,"$.headers.Hello");
    assertEquals("tom",word);
}
 响应内容
{
    "args": {
        
    },
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip,deflate",
        "Hello": "tom",
        "Host": "httpbin.ceshiren.com",
        "Sw8": "1-ODJhOGFkZ...jZQ==",
        "User-Agent": "Apache-HttpClient/4.5.13 (Java/21.0.1)",
        "X-Forwarded-Host": "httpbin.ceshiren.com"
    },
    "origin": "111.18.134.110, 182.92.156.22",
    "url": "https://httpbin.ceshiren.com/get"
}

 

3.4 数据结构比对SJONSchema

CourseSchema.json

{
    "name": "Green",
    "rank":1,
    "courses":[
        "java",
        "python",
        "shell"
        ]
}

观察右侧的解析结果,可以发现Schema就是描述key值及其对应的Value属性。
作用:json schema用来校验json数据结构。
应对复杂的json格式,判断响应的key值及类型,value的类型。如果不同,即抛出错误
示例:通过对比响应文件和Schema,发现数据结构是否一致

JsonSchema解析地址

{
    "$schema": "http://json-schema.org/draft-06/schema#",
    "$ref": "#/definitions/CourseSchema",
    "definitions": {
        "CourseSchema": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "name": {
                    "type": "string"
                },
                "rank": {
                    "type": "integer"
                },
                "courses": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            },
            "required": [
                "courses",
                "name",
                "rank"
            ],
            "title": "CourseSchema"
        }
    }
}
 
/**
* groupId:io.rest-assured
* artfactId:json-schema-validator
*/
@Test
public void testJsonSchema(){
    given()
    .when()
        .get("https://httpbin.org/get")
    .then()
        .log().all()
        .assertThat()
        .body(matchesJsonSchemaInClasspath("schemademo.json"))
        .statusCode(200);
    }

4. 其他

代理

介于客户端与服务端之间,可以监听请求和响应信息,充当防火墙和web过滤器

@Test
public void setProxy(){
    //方式1:设置全局代理,忽略HTTPS校验
    RestAssured.proxy("localhost",8888);
    RestAssured.useRelaxedHTTPSValidation();
    given()
        /** 方式2:设置局部代理,忽略HTTPS校验
        .proxy("127.0.0.1",8888)
        .relaxedHTTPSValidation()
        */
    .when()
        .get("https://httpbin.org/get")
    .then()
        .log().all()
        .statusCode(200);
}

header

通用消息头、请求消息头、响应消息头、实体消息头

@Test
public void testHeader(){
    given()
        .header("User-Agent","tom")
    .when()
        .get("https://httpbin.org/get")
    .then()
        .statusCode(200)
        .log().all()
        .body("headers.User-Agent",equalTo("tom"));
}
@Test
public void testCookie(){
    given()
        //方式1:通过header添加
        .header("Cookie","my_cookie=china")
        //方式2:通过cookie添加
        .cookie("cat","tom")
        .cookies("mouse","jerry","dog","feen")
        .log().all()
    .when()
        .get("https://httpbin.org/get")
    .then()
        .statusCode(200);
    }

 

posted on 2018-08-06 12:53  singleSpace  阅读(331)  评论(0)    收藏  举报