一、背景

现在,越来越多的 Web 应用转向了 RESTful 的架构,很多产品和应用暴露给用户的往往就是一组 REST API,这样有一个好处,用户可以根据需要,调用不同的 API,整合出自己的应用出来。

Rest-Assured 是一套由 Java 实现的 REST API 测试框架,它是一个轻量级的 REST API 客户端,可以直接编写代码向服务器端发起 HTTP 请求,并验证返回结果;它的语法非常简洁,是一种专为测试 REST API 而设计的 DSL。用行为驱动的方式来执行接口测试,使不懂代码的人也能轻松上手,看懂并编写一些测试脚本。

二、Rest-Assured框架搭建步骤

2.1 创建maven项目

  • 打开idea创建maven项目,选择相关配置点击next;

  • 输入项目名称,点击next;

  • 选择自己安装的maven信息,点击完成即可,idea会自动下载相关maven依赖包;

2.2 配置maven相关依赖

  • 在项目的pom.xml中增加Rest-Assured的依赖;

io.rest-assuredrest-assured4.4.0io.rest-assuredjson-schema-validator4.4.0io.rest-assuredjson-path4.4.0

其中json-schema-validator为对接口请求结果通过schema断言所需依赖包

  • 在项目的pom.xml中增加Junit、testng依赖;

junitjunit4.13.2testorg.testngtestng7.4.0compile

三、接口测试案例

3.1 一个简单的接口测试用例

public static Headers US_QA_SIT_header(){String access_token = Token.UsqaSitSubAdminToken();Header header1 = new Header("Authorization","Bearer " + access_token);Header header2 = new Header("Content-Type", "application/json");Header header3 = new Header("x-subscription","xxxxxxxxxx");Header header4 = new Header("x-tenant","xxx");Headers headers = new Headers(header1,header2,header3,header4);return headers;}@Testpublic void test01GetApps(){ValidatableResponse response = given().headers(HeaderTest.US_QA_SIT_header()).when().get(base_url).then().statusCode(200);}
  • given():一次网络请求所需条件参数都写在这里,包括header、body、cookie等信息;

  • when():触发条件,后面带http请求,get、post、delete等;

  • then():断言;

上面例子为获取APP列表,get请求带header信息,断言statuscode是否等于200,没有做进一步的断言。

3.2 参数信息

3.2.1 cookie信息

通常模式下可以通过以下方法指定一个cookie或多个cookie:

given().cookie("cookie_name","value").when().get("/cookie").then().assertThat();given().cookie("cookie_name","value1","value2");//这样创建两个cookie,cookie_name=value1和cookie_name=value2Cookie cookie1 = Cookie.Builder("cookie1","value1").build();Cookie cookie2 = Cookie.Builder("cookie2","value2").build();Cookie cookies = new Cookies(cookie1,cookie2);

3.2.2 header信息

同cookie信息一样可以单个指定、一个header名称对应多个值、同时指定多个header:

given().header("header1","value1").when().get("/list").then();given().header("header","value1","value2").when().get("/list").then();given().header("header1","value1").header("header2","value2").when().get("/list").then();Header header1 = new Header("header1","value1 ");Header header2 = new Header("header2", "value2");Headers headers = new Headers(header1,header2);

3.2.3 content-type信息

content-type信息可以放在header中也可以用contentType方法:

given().header("Content-Type", "application/json").when().get("/list").then();given().contentType().when("application/json").get("/list").then();

如果需要接口需要上传文件,content type为multipart/form-data类型。

3.2.4 请求参数化

通常情况下可以使用body直接带完整请求参数来完成请求,参数化可以通过param进行请求:

given().body("{\"username\":\"wy\",\"password\":\"123456\"}").when().post("/login").then;given().param("username","wy").param("password","123456").when().post("/login").then;

rest-assured将根据http请求类型自动确定参数为查询参数或表单参数,如一个请求中包含两种参数,可以这样使用

given().formParam("username","wy").queryParam("list").when().post(url).then();

参数如果是上传的文件,则需使用multi-part方法传递:

@Test(timeOut = 300000)public void test03UploadApp(){File filedir = new File("");String filePath = null;try {filePath = filedir.getCanonicalPath();} catch (IOException e) {e.printStackTrace();}String file_dir = filePath + "\\src\\test\\resources\\package\\Youku_V8.6.8.200420.0001_ab235fdcb823d83f.apk";ValidatableResponse response = given().headers(HeaderTest.US_QA_SIT_header_multipart()).header("x-file-content-length", 103616863).multiPart(new File(file_dir)).when().post(base_url +youku_id +"/upload").then().statusCode(200);}

多值参数可以使用var-args或list指定:

given().param("param","value1","value2").when().post(url).then();List values = new ArrayList();values.add("value1");values.add("value2");given().param("param",values).when().post(url).then();

路径参数可以在选择时指定,也可以使用路径参数指定:

given().when().post("/{location1)/{location2}","country","city").then();given().pathParam("location1","country").pathParam("location2","city").when().get(url).then();

从某个接口请求中获得数据作为下一个接口入参时,可以直接请求接口根据返回值json路径来获取:

String param = get("/name").then().body("path1.path2")

3.3 断言

3.3.1 响应体断言

断言返回体中的某个值,可以使用jsonPath路径找到要断言的参数,再根据所需断言类型进行判断:

@Testpublic void test10GetFilePath(){ValidatableResponse response = given().headers(HeaderTest.US_QA_SIT_AR_header()).when().get(base_url).then().body("path1.path2",equals("value")).body("path1.path2",hasItem("value")).body("path1.path2",hasXpath("value"))}

如果想对整个请求体进行完全断言,可以导入json schema validation包,并配置请求返回体的json schema文件,即可进行整个body的断言;

Schema样式:

{"$schema": "http://json-schema.org/draft-04/schema#","title": "Product set","type": "array","items": {"title": "Product","type": "object","properties": {"id": {"description": "The unique identifier for a product","type": "number"},"name": {"type": "string"},"price": {"type": "number","minimum": 0,"exclusiveMinimum": true},"tags": {"type": "array","items": {"type": "string"},"minItems": 1,"uniqueItems": true},"dimensions": {"type": "object","properties": {"length": {"type": "number"},"width": {"type": "number"},"height": {"type": "number"}},"required": ["length", "width", "height"]},"warehouseLocation": {"description": "Coordinates of the warehouse with the product","$ref": "http://json-schema.org/geo"}},"required": ["id", "name", "price"]}}

3.3.2 状态码断言

given().body("body").when().get(url).then().statusCode(200);given().body("body").when().get(url).then().assertThat().statusLine("message");given().body("body").when().get(url).then().assertThat().statusLine(containString("message"));

3.3.3 header断言

given().body("body").when().get(url).then().header("header","value");given().body("body").when().get(url).then().headers("header1","value1", "header2","value2"...);given().body("body").when().get(url).then().headers("header1","value1", "header2",containString("value2")...);

总结

上文中阐述了rest-assured的项目搭建和一些基础用法,通过具体实展示如何传参、请求、断言,满足了接口测试的基础需求,它还提供许多日志、认证、重定向、解码等功能,感兴趣的同学可以继续探索。

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

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