zoukankan      html  css  js  c++  java
  • java调用接口(rest-assured)

    参考来源:https://blog.csdn.net/u011622109/article/details/106904955

    官网:https://rest-assured.io/

    文档翻译: https://iworkh.gitee.io/blog/2020/06/17/java_rest_assured_wiki_info/

    一、被测试的接口准备,来自于上面的参考,spring boot框架

    响应类

    import com.fasterxml.jackson.annotation.JsonProperty;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class JsonDataResult<T> {
            protected boolean success;
            protected String message;
            protected int errorCode = 0;
    
            @JsonProperty("result")
            protected T data;
    }
    View Code

    实体类

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import java.util.Date;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class UserVo {
        private int id;
        private String name;
        private Date birthday;
        private boolean vip;
    }
    View Code

    controller

    import com.example.demo.pojo.JsonDataResult;
    import com.example.demo.pojo.UserVo;
    
    import org.springframework.web.bind.annotation.*;
    
    import java.util.Date;
    import java.util.Random;
    
    @RestController
    @RequestMapping("/api/user")
    public class UserController {
    
        @PostMapping("/createUserByParam")
        public JsonDataResult<Boolean> createUserByParam(UserVo userVo) {
            JsonDataResult<Boolean> result = new JsonDataResult<>();
            userVo.setId(new Random().nextInt(50));
            result.setSuccess(true);
            result.setData(true);
            return result;
        }
    
        @PostMapping("/createUserByJson")
        public JsonDataResult<Boolean> createUserByJson(@RequestBody UserVo userVo) {
            JsonDataResult<Boolean> result = new JsonDataResult<>();
            userVo.setId(new Random().nextInt(100));
            result.setSuccess(true);
            result.setData(true);
            return result;
        }
    
        @GetMapping("/{id}")
        public JsonDataResult<UserVo> getUser(@PathVariable int id) {
            JsonDataResult<UserVo> result = new JsonDataResult<>();
            String[] hobbies = {"football", "sing"};
            //从数据库查询,省略
            UserVo user = new UserVo(id, "测试名字" + id, new Date(), true);
            result.setSuccess(true);
            result.setData(user);
            return result;
        }
    
        @PutMapping
        public JsonDataResult<UserVo> updateUser(@RequestBody UserVo userVo) {
            JsonDataResult<UserVo> result = new JsonDataResult<>();
            //从数据库删除,省略
            result.setSuccess(true);
            result.setData(userVo);
            return result;
        }
    
        @DeleteMapping("/{id}")
        public JsonDataResult<Boolean> delteUser(@PathVariable int id) {
            JsonDataResult<Boolean> result = new JsonDataResult<>();
            //从数据库删除,省略
            result.setSuccess(true);
            result.setData(true);
            return result;
        }
    }
    View Code

    二、依赖,杂七杂八一堆

       <dependency>
                <groupId>io.rest-assured</groupId>
                <artifactId>rest-assured</artifactId>
                <version>4.4.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>io.rest-assured</groupId>
                <artifactId>json-path</artifactId>
                <version>4.4.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>io.rest-assured</groupId>
                <artifactId>json-schema-validator</artifactId>
                <version>4.0.0</version>
            </dependency>
            <dependency>
                <groupId>io.rest-assured</groupId>
                <artifactId>xml-path</artifactId>
                <version>4.4.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>io.rest-assured</groupId>
                <artifactId>rest-assured</artifactId>
                <version>4.4.0</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>io.rest-assured</groupId>
                <artifactId>rest-assured-common</artifactId>
                <version>4.4.0</version>
                <scope>compile</scope>
            </dependency>
    View Code

    三、语法链
    given()--when()--then()
    1、given 后面,  设置参数、头、认证
    2、when() 后面,  请求rest接口,get、post、put、delete等
    3、then() 后面,    验证结果。

    四、2个静态引用,一个是框架本身,一个是用于校验使用

    // 官方推荐静态引用
    import static io.restassured.RestAssured.*;
    import static org.hamcrest.Matchers.*;

    五、入参

     @Test
        public void testParams() {
            // 1、given() 是RestAssured类下一个方法,官方文档强烈推荐使用静态导入语句
    // 2、get方法,对应GET请求,这一步已经请求完成了
            // 3、then() 为后面对response消息做判断时做准备
            HashMap<String, String> params = new HashMap<String, String>();
            params.put("userId", "2");
            params.put("id", "14");
    
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("accept-encoding", "gzip,deflate");
            headers.put("accept-language", "zh-CN");
    
            given().
                    // 调用效果:http://jsonplaceholder.typicode.com/posts?id=14&userId=2
                    // 这个貌似和params一样的效果
                    queryParams(params).
                    // params(params).
                    // param只能设置一个参数,多调用几次可以多设置几个参数,下面的header类似
                    // param("userId", 2).
                    // 多个头字段
                    headers(headers).
                    // header("accept-encoding", "gzip,deflate").
                when().
                    // 请求前的log 是打印请求参数信息
                    // log().all().
                        get("http://jsonplaceholder.typicode.com/posts").
                then().
                    // 请求后的log 是打印响应参数信息
                        log().body();
        }
    @Test
        public void testAssert() {
            given().
                    // 效果 http://jsonplaceholder.typicode.com/posts/3
                    // 把下面地址中的变量替换掉
                        pathParam("section", "posts").
                        pathParam("id", "3").
                 when().
                        get("http://jsonplaceholder.typicode.com/{section}/{id}");
    } 
     @Test
        public void test0011() {
            UserVo user = new UserVo(1, "zhangsan", new Date(), false);
    
            given().
                    // 直接传入对象
                    body(user).
                    // 两种设置入参类型
                    header("Content-Type", "application/json; charset=utf-8").
                    // contentType("application/json; charset=utf-8");
                when().
                    post("/api/user/createUserByParam");
    }

    六、响应信息处理

        @Test
        public void test001() {
            // 这里没有设置baseurl,但是依然请求成功了。因为框架有默认的url:http://localhost:8080
            Response response = get("/api/user/3");
            // 使用 as 将响应转化为我们需要的对象
            JsonDataResult j = response.as(JsonDataResult.class);
            // 拿到响应后也可以用testng本身的断言
            Assert.assertEquals(j.isSuccess(),true);
        }
     @Test
        public void testResponse() {
            // 在没有参数设置的前提下,可以直接请求,拿到响应
            Response r = get("https://reqres.in/api/users/2");
    
            System.out.println("直接获取的响应结果:" + r.asString());
            System.out.println("获取请求头:" + r.getHeaders());
            System.out.println("获取请求头某个字段:" + r.getHeader("Content-Type"));
            System.out.println("获取cookies:" +r.cookies());
            System.out.println("毫秒:" + r.time());
            System.out.println("毫秒,会损失精度:" + r.timeIn(TimeUnit.SECONDS));
    
            Integer id = r.
                    then().
                    // json、xm都可以使用xpath路径
                    body("data.id", is(2)).
                    // 通过extract().path() 摘取内容
                    extract().
                    path("data.id");
    
            Response response = r.
                    then().
                    extract().
                    response();
            System.out.println("间接获取到的响应和直接获取的响应比较:" + ( response == r ));
            System.out.println("间接获取到的id和直接获取的id比较:" + ( id == r.path("data.id") ));
        }

    七、框架自带的响应断言

        @Test
        public void testAssert() {
            given().
                        pathParam("section", "posts").
                        pathParam("id", "3").
                    when().
                        get("http://jsonplaceholder.typicode.com/{section}/{id}").
                    then().
                    // 下面的断言是线性断言,一旦某个断言失败,后面就不会继续执行
                    //断言200
                        statusCode(200).
                    // 断言返回的格式对象,例如XML、HTML、TEXT等
                        contentType(ContentType.JSON).
                    // 断言响应头字段,header单个,headers多个
                        header("Content-Type", "application/json; charset=utf-8").
                        headers("Content-Type", "application/json; charset=utf-8", "Connection", "keep-alive").
                    // Matchers提供了很多匹配方式,equalTo、containsString。hasItem、hasItems这2个我没用成功
                        body(containsString("ea molestias quasi exercitationem")).
                        body("userId", equalTo(1)).
    
                    // body("title", hasItem("ea molestias quasi exercitationem repellat qui ipsa sit aut")).
                    // 不同节点相同的key有对应的value,例如:{{"title": "value1"},{"title": "value2"}},
                    // 则不能使用equalTo、hasItem,可以使用hasItems(要求把所有的value列出来)
                    // body("title", hasItems("ea molestias quasi exercitationem repellat qui ipsa sit aut")).
    
                    // 断言响应时间小于2000毫秒,参数类型是long
                       time(lessThan(2000L)).
                    log().body();
        }

    八、base信息设置、请求封装RequestSpecification、响应封装ResponseSpecification

    public class TC41 {
        RequestSpecification requestSpc;
        ResponseSpecification responseSpc;
    
        @BeforeClass
        public void setup() {
            // 这里设置了 baseURI、basePath,后面get则不需要再填这2个信息
            RestAssured.baseURI = "http://jsonplaceholder.typicode.com";
            // RestAssured.port = 80;
            RestAssured.basePath = "/posts";
            // 恢复成默认设置
            // RestAssured.reset();
    
            //  利用RequestSpecification对象来封装一些请求数据
            RequestSpecBuilder builder = new RequestSpecBuilder();
            builder.addParam("userId", "2");
            builder.addHeader("Accept-Encoding", "gzip, deflate");
            requestSpc = builder.build();
    
            //  利用ResponseSpecification对象来封装一些响应判断的数据
            ResponseSpecBuilder rb = new ResponseSpecBuilder();
            rb.expectStatusCode(200);
            rb.expectHeader("Content-Type", "application/json; charset=utf-8");
            rb.expectHeader("Cache-Control", "max-age=43200");
            responseSpc = rb.build();
       }
    
        @Test
        public void test1() {
            given().
                    spec(requestSpc).log().all().
                    when().
                    get().
                    then().
                    spec(responseSpc).
                    // 如果错误就打印日志
                    log().ifError();
        }
    }

    九、其他内容

    public class TestBase {
    
        public static RequestSpecification httpRequest;
        public static Response response;
        public Logger logger;
    
        public static String serverHost;
        public static String port;
    
        // 静态代码块,随着类的加载而执行,而且只执行一次
        static {
            // 用于加载properties文件,入参不需要文件扩展名.properties
            ResourceBundle rb = ResourceBundle.getBundle("config");
            serverHost = rb.getString("Host");
            port = rb.getString("Port");
        }
    
        @BeforeClass
        public void setup() {
            String className = this.getClass().getName();
            logger = Logger.getLogger(className);
    
    //        PropertyConfigurator.configure("log4j.properties");
    //        logger.setLevel(Level.DEBUG);
    //        logger.info("host: " + serverHost);
    //        logger.info("port: " + port);
        }
    
    }
    一个只会点点点的测试,有疑问可以在测试群(群号:330405140)问我
  • 相关阅读:
    docker国内镜像地址
    springBoot+websocket集群系列知识
    多个idea项目使用同一个tomcat
    nginx+tomcat遇到的https重定向到http问题
    设置常用错误页面自定义显示
    mysql关于索引的一些零碎知识点(持续更新)
    Idea使用Lombok简化实体类代码
    mysql索引分类及实现原理
    使用SpringSession和Redis解决分布式Session共享问题
    HashMap ConcurrentHashMap解读
  • 原文地址:https://www.cnblogs.com/yinwenbin/p/15366943.html
Copyright © 2011-2022 走看看