rest-assured接口测试学习(三)

2019-05-31  本文已影响0人  DayBreakL

前文:
rest-assured接口测试学习(一)
rest-assured接口测试学习(二)

补充知识

一、全局封装

1.全局RestAssured对象
2.spec方法通用的断言

每个请求都会共用的参数:比如URI 、cookies,或者每个接口都有的断言statusCode是200……可以使用specification

public class Baidu {
    public static RequestSpecification requestSpecification;
    public static ResponseSpecification responseSpecification;
    @Before
    public void gen(){
        //通用请求
        requestSpecification=new RequestSpecBuilder().build();
        requestSpecification.port(80);
        requestSpecification.cookie("s_id","leitianxiao");
        requestSpecification.header("User-Agent","Andriod");
        //通用断言
        responseSpecification=new ResponseSpecBuilder().build();
        responseSpecification.statusCode(200);
        responseSpecification.body(hasItems("0","1"));

//其他用例里使用
@Test
    public void testGetHtml(){
        given().
                //请求使用
                spec(requestSpecification);
                get("http://www.baidu.com").
        then().
                //断言使用
                spec(responseSpecification);
    }
}
3.filter方法进行加解密封装(利用filter机制实现自动解密)

(这里没大懂~~)

————————————
filter相当于过滤器、拦截器,在请求之前可以改掉请求信息,如URL,然后传给ctx调用链,调用链发送篡改后的请求,调用链获得response,可以进行篡改,篡改之后才会返回response

顺序:
//code
//filter request
//real response
//filter response
//return response
//then断言

解密原理是在得到real response进行解密,通过filter response把解密的response返回。

tips:
这里maven构建时报错-source 1.5 中不支持 lambda 表达式filter((req,res,ctx)->{//重新生成response})是jdk8的 lambda 表达式,Maven Compiler 插件默认会加 -source 1.5 及 -target 1.5 参数来编译(估计是为了兼容一些比较老的 Linux 服务器操作系统,它们通常只有 JDK 5),而我们的代码里使用了 JDK 7/8 的语法。

解决:pom.xml文件<project>下添加:

 <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

————————————

public void testUserInfo(){
        given().log().all().proxy("127.0.0.1").//设置代理抓包
                filter((req,res,ctx)->{
                    //自行给请求头加上id=tester字段
                   req.header("id","tester");
                   //把请求发出去
                    Response resOrigin=ctx.next(req,res);
                    //把响应返回
                    return resOrigin;
                        }).
                when().
                get("/data/userinfo").
                then().log().all().
                spec(responseSpecification);
    }

通过charles可以看到,请求头里有了id=tester字段,但是用log().all()打印没有,这说明在真实请求发起时,并不知道有id这个字段,通过filter后,在真实对外发送时增加了这个字段。

应用:
全局的filter,所有请求加一个通用的请求信息(比如cookie)放在@Before,可以通过if判断。

RestAssured.filter((req,res,ctx)->{
    //如果URI里包含xueqiu.com,请求头上加上cookie信息
    if (req.getURI().contains("xueqiu.com")){
                    //自行给请求头加上id=tester字段
                   req.header("cookie","……");
                   //把请求发出去
                    Response resOrigin=ctx.next(req,res);
                    //把响应返回
                    return resOrigin;
                       } }).

——————————

示例:

given().filter((req,res,ctx)->{
            //把请求发出去
            Response resOrigin=ctx.next(req,res);
            //克隆原来的response
            ResponseBuilder responseBuilder=new ResponseBuilder().clone(resOrigin);
            //setbody是修改把返回来的body
            responseBuilder.setBody("hello world");
            //新的response
            Response resNew =responseBuilder.build();
            //返回新的response
            return resNew;
        })

应用:

{
    "q": "sogo",
    "page": 1,
    "size": 3,
    "stocks": [{
        "code": "SOGO",
        "name": "搜狗",
        "enName": "",
        "hasexist": "false",
        "flag": null,
        "type": 0,
        "stock_id": 1029472,
        "ind_id": 0,
        "ind_name": "通讯业务",
        "ind_color": null,
        "_source": "sc_1:1:sogo"
    }]
}

响应原本是这种json格式,我们的断言是

then().
                statusCode(200).
                body("stocks.name",equalTo("搜狗"));

可能因为某些原因,响应需要加密(以base64加密为例),返回的是加密的响应,这个时候你使用业务断言是会报错的:


ewoJInEiOiAic29nbyIsCgkicGFnZSI6IDEsCgkic2l6ZSI6IDMsCgkic3RvY2tzIjogW3sKCQkiY29kZSI6ICJTT0dPIiwKCQkibmFtZSI6ICLmkJzni5ciLAoJCSJlbk5hbWUiOiAiIiwKCQkiaGFzZXhpc3QiOiAiZmFsc2UiLAoJCSJmbGFnIjogbnVsbCwKCQkidHlwZSI6IDAsCgkJInN0b2NrX2lkIjogMTAyOTQ3MiwKCQkiaW5kX2lkIjogMCwKCQkiaW5kX25hbWUiOiAi6YCa6K6v5Lia5YqhIiwKCQkiaW5kX2NvbG9yIjogbnVsbCwKCQkiX3NvdXJjZSI6ICJzY18xOjE6c29nbyIKCX1dCn0=

tips:
base64命令可以直接将响应转为base64加密形式

用python快速生成一个本地8000端口的小网站来演示这种情况:
vim base64.json //把加密了的json内容写入base64.json中
python -m CGIHTTPServer

@Test
    public void testBase64(){
        given().
                get("http://127.0.0.1:8000/base64.json").prettyPeek().
        then().
                statusCode(200).
                body("stocks.name",hasItems("搜狗"));
    }

把上文的示例中responseBuilder.setBody("hello world");的“hello world”改为解密后的响应body即可。
代码如下:

 @Test
    public void testBase64(){
        given().filter((req,res,ctx)->{
            //把请求发出去
            Response resOrigin=ctx.next(req,res);
            //克隆原来的response
            ResponseBuilder responseBuilder=new ResponseBuilder().clone(resOrigin);
            //使用Base64的库
            //Base64.getDecoder().decode()对resOrigin的body进行解码
            //转为string格式,trim()去掉字符串两端多余空格。
            String decode=new String(
                    Base64.getDecoder().decode(
                            resOrigin.body().asString().trim()
                    )
            );
            //setbody是修改把返回来的body
            responseBuilder.setBody(decode);
            //新的response
            Response resNew =responseBuilder.build();
            //返回新的response
            return resNew;
        }).
                get("http://127.0.0.1:8000/base64.json").prettyPeek().
        then().
                statusCode(200).
                body("stocks.name",hasItems("搜狗"));
    }
}

解密之后可以正常使用我们的业务断言


二、对接口时间进行断言

when().
            get("/lotto").
then().
            time(lessThan(2000L));//响应时间不超过2000毫秒

除了进行功能测试,对响应时间有个基本的要求

三、schema自动校验

RestAssured有一套自己的schema自动校验机制

schema自动生成方法
(需要很深的算法功底,自己写工具,自动扫描公司接口,自动生成对应的schema文件)

实践

  1. 导入依赖
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>3.0.1</version>
</dependency>
  1. 一般Schema的文件比较大,使用时,通常存成一个的文件。


  2. 调用matchesJsonSchemaClasspath等系列方法
    静态导入:import static io.restassured.module.jsv.JsonSchemaValidator.*;
    常用断言方式一:assertThat().body(matchesJsonSchemaInClasspath("data/userInfo-schema.json"));
    常用断言方式二:assertThat().body(matchesJsonSchema(new File("data/userInfo-schema.json")));

故意写错一个验证类型看看效果,把本应该是string类型的改为boolean。




warning可以先不管,找到error~可以看出说实例类型是string,而被允许的类型是boolean。


四、https请求

useRelaxedHTTPSValidation(); //信任https请求

上一篇 下一篇

猜你喜欢

热点阅读