RestAssured + cucumber接口测试框架
2020-07-19 本文已影响0人
杜艳_66c4
1、总的框架:
总的框架
2、pom.xml
<dependencies>
<!--ccucumber 相关依赖-->
<!--<dependency>-->
<!--<groupId>info.cukes</groupId>-->
<!--<artifactId>cucumber-java8</artifactId>-->
<!--<version>1.2.4</version>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-html -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-html</artifactId>
<version>0.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.2.4</version>
</dependency>
<!--rest-assured 接口测试框架-->
<!-- https://mvnrepository.com/artifact/com.jayway.restassured/rest-assured -->
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
</dependency>
<!--log 引入-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
<scope>provided</scope>
</dependency>
<!--compare json-->
<dependency>
<groupId>net.javacrumbs.json-unit</groupId>
<artifactId>json-unit</artifactId>
<version>1.13.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<reuseForks>false</reuseForks>
<!--<skipTests>true</skipTests>-->
</configuration>
</plugin>
</plugins>
</build>
ApiTools
package com.tools.apitools;
import com.jayway.restassured.response.Response;
import com.tools.config.LoggerControler;
import com.tools.steps.Steps;
import org.testng.annotations.Test;
import static com.jayway.restassured.RestAssured.given;
/**
* Created by vidorh on 7/28/2016.
*/
public class ApiTools {
static LoggerControler log = LoggerControler.getLogger(ApiTools.class);
/**
* 带json的post请求
*
* @param apiPath api地址
* @param json 请求json
* @return api返回的Response
*/
public static Response post(String apiPath, String json) {
// 开始发起post 请求
Response response = given().
contentType("application/json;charset=UTF-8").
headers("appId", "2486cd2d0ea749298f749d7b91a19685").
//cookies("cookies1", "values1", "cookies2", "values2").
body(json).
when().log().all().post(apiPath.trim());
// log.info(response.statusCode());
System.out.println("statusCode: " + response.statusCode());
log.info("reponse:");
response.getBody().prettyPrint();
return response;
}
/**
* 非json形式的post请求, 暂时不用的哦
*
* @param apiPath api地址
* @return api返回
*/
/* public static Response post(String apiPath) {
// Cookie someCookie = new Cookie.Builder("JSESSIONID", jsessionid).setSecured(true).setComment("some comment").build();
Response response = given().
contentType("application/json;charset=UTF-8").
headers("headers1", "value1", "headers2", "values2").
cookies("cookies1", "values1", "cookies2", "values2").
when().log().all().post(apiPath.trim());
log.info(response.statusCode());
log.info("reponse:");
response.getBody().prettyPrint();
return response;
}*/
/**
* get 请求
*
* @param apiPath api路径
* @return api的response
*/
public static Response get(String apiPath,String json) {
Response response = given().
contentType("application/json;charset=UTF-8").
headers("appId", "2486cd2d0ea749298f749d7b91a19685").
body(json).
// cookies("cookies1", "values1", "cookies2", "values2").
when().log().all().get(apiPath.trim());
log.info(response.statusCode());
log.info("reponse:");
response.getBody().prettyPrint();
return response;
}
/**
* 获取json中某个key值
*
* @param response 接口返回
* @param jsonPath jsonpath, 例如 a.b.c a.b[1].c a
* @return
*/
public static String getJsonPathValue(Response response, String jsonPath) {
String reponseJson = String.valueOf(response.jsonPath().get(jsonPath));
// String jsonValue = String.valueOf(from(reponseJson).get(jsonPath));
return reponseJson;
}
}
MyAssert.java
package com.tools.apitools;
import com.tools.config.LoggerControler;
import org.testng.Assert;
import java.util.regex.Pattern;
/**
* Created by vidorh on 8/1/2016.
* <p>
* 居于Testng Assert类二次封装,添加办法校验方式
*/
public class MyAssert extends Assert {
static final LoggerControler logger = LoggerControler.getLogger(MyAssert.class);
// 而外添加的校验方法 =======================================================================
/**
* 断言字符是否以某个字符串开头
*
* @param message 断言错误消息
* @param content 待断言字符串
* @param prefix 前缀表达式
*/
public static void assertStartWith(String content, String prefix, String message) {
if (message != null)
logger.info(message);
if (content.startsWith(prefix)) {
logger.info("前缀匹配校验成功");
} else {
logger.error("前缀匹配校验失败!\n待校验的字符窜为:" + content + "\n校验的前缀表达式为:" + prefix);
MyAssert.fail();
}
}
/**
* 断言字符是否以某个字符串开头
*
* @param content 待断言字符串
* @param prefix 前缀表达式
*/
// 重载
public static void assertStartWith(String content, String prefix) {
MyAssert.assertStartWith(content, prefix, null);
}
/**
* 断言字符是否已某个字符串结尾
*
* @param message 断言错误消息
* @param content 待断言字符串
* @param endfix 前缀表达式
*/
public static void assertEndWith(String content, String endfix, String message) {
if (message != null)
logger.info(message);
if (content.endsWith(endfix)) {
logger.info("后缀匹配校验成功!");
} else {
logger.error("后缀匹配校验失败!\n待校验的字符窜为:" + content + "\n校验的后缀表达式为:" + endfix);
MyAssert.fail();
}
}
/**
* 断言字符是否已某个字符串结尾
*
* @param content 待断言字符串
* @param endfix 前缀表达式
*/
public static void assertEndWith(String content, String endfix) {
MyAssert.assertEndWith(content, endfix, null);
}
/**
* 根据正则表达式断言是否匹配
*
* @param message 断言错误信息
* @param matcher 待校验的字符串
* @param regex 校验的正则表达式
*/
public static void assertMatch(String matcher, String regex, String message) {
if (message != null)
logger.info(message);
if (Pattern.matches(regex, matcher)) {
logger.info("匹配校验成功!");
} else {
logger.error("匹配校验失败!\n待校验的字符串为:" + matcher + "\n校验的正则表达式为:" + regex);
MyAssert.fail();
}
}
/**
* 根据正则表达式断言是否匹配
*
* @param matcher 待校验的字符串
* @param regex 校验的正则表达式
*/
public static void assertMatch(String matcher, String regex) {
MyAssert.assertMatch(matcher, regex, null);
}
/**
* 根据正则表达式断言是否匹配
*
* @param message 断言错误信息
* @param matcher 待校验的字符串
* @param regex 校验的正则表达式
*/
public static void assertNoMatch(String matcher, String regex, String message) {
if (message != null)
logger.info(message);
if (!Pattern.matches(regex, matcher)) {
logger.info("匹配校验成功!");
} else {
logger.error("匹配校验失败!\n待校验的字符串为:" + matcher + "\n校验的正则表达式为:" + regex);
MyAssert.fail();
}
}
/**
* 根据正则表达式断言是否匹配
*
* @param matcher 待校验的字符串
* @param regex 校验的正则表达式
*/
public static void assertNoMatch(String matcher, String regex) {
MyAssert.assertNoMatch(matcher, regex, null);
}
/**
* 断言字符串中是否包含某些字符
*
* @param message 断言错误消息
* @param content 断言的字符串为
* @param included 包含的字符串
*/
public static void assertInclude(String content, String included, String message) {
if (message != null)
logger.info(message);
if (content.contains(included)) {
logger.info("匹配校验成功!");
} else {
logger.error("匹配校验失败!\n待校验的字符串为:" + content + "\n包含字符串为:" + included);
MyAssert.fail(message);
}
}
/**
* 断言字符串中是否包含某些字符
*
* @param content 断言的字符串为
* @param included 包含的字符串
*/
public static void assertInclude(String content, String included) {
MyAssert.assertInclude(content, included, null);
}
}
LoggerControler.java
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* Created by vidorh on 7/28/2016.
*/
public class LoggerControler {
private static Logger logger = null;
private static LoggerControler logg = null;
public static LoggerControler getLogger(Class<?> T) {
if (logger == null) {
// 实例化一个 Properties 类,处理log4j.Properties文件
Properties props = new Properties();
try {
// 获取log4j配置文件路径
String envPaht = System.getProperty("user.dir") +
File.separator + "config" + File.separator + "log4j.properties";
InputStream is = new FileInputStream(envPaht);
props.load(is);
} catch (IOException e) {
e.printStackTrace();
}
// log4j 的PropertyConfigurator 类的configure方法输入数据流
PropertyConfigurator.configure(props);
logger = Logger.getLogger(T);
logg = new LoggerControler();
}
return logg;
}
/**
* 重写logger方法
*/
public void info(Object msg) {
logger.info(msg);
}
public void debug(Object msg) {
logger.debug(msg);
}
public void warn(Object msg) {
logger.warn(msg);
}
public void error(Object msg) {
logger.error(msg);
}
}
ReadTxtFile.java
package com.tools.filetools;
import com.tools.config.LoggerControler;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* Created by vidorh on 8/2/2016.
*/
public class ReadTxtFile {
static final LoggerControler logger = LoggerControler.getLogger(ReadTxtFile.class);
//file.separator这个代表系统目录中的间隔符,说白了就是斜线,不过有时候需要双线,有时候是单线,你用这个静态变量就解决兼容问题了。
static String path = System.getProperty("user.dir") + File.separator + "jsondir" + File.separator;
public static String readTxtFile(String fileName) {
//用户的当前工作目录
System.out.println("user.dir : "+System.getProperty("user.dir"));
String lineTxt = null;
StringBuffer stringBuffer = null;
try {
File file = new File(path + fileName);
//判断文件是否存在
if (file.isFile() && file.exists()) {
InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8");
BufferedReader bufferedReader = new BufferedReader(read);
stringBuffer = new StringBuffer();
while ((lineTxt = bufferedReader.readLine()) != null) {
stringBuffer.append(lineTxt);
System.out.println(lineTxt);
}
logger.info(stringBuffer);
read.close();
} else {
logger.error("找不到指定的文件");
}
} catch (Exception e) {
logger.error("读取文件内容出错");
e.printStackTrace();
}
return String.valueOf(stringBuffer);
}
}
Steps.java
package com.tools.steps;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.restassured.mapper.ObjectMapperDeserializationContext;
import com.jayway.restassured.mapper.ObjectMapperSerializationContext;
import com.jayway.restassured.response.Response;
import com.tools.apitools.ApiTools;
import com.tools.apitools.MyAssert;
import com.tools.config.JsonTestObject;
import com.tools.filetools.ReadTxtFile;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import java.util.*;
import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
import static net.javacrumbs.jsonunit.JsonAssert.setOptions;
/**
* Created by vidorh on 8/1/2016.
* <p>
* Steps 集合
*/
public class Steps {
//所有的响应
Map<String, Response> responses = new HashMap<>();
//某一个接口的相应
Response response = null;
/*
1、. 匹配任意除换行符“\n”外的字符;
2、*表示匹配前一个字符0次或无限次;
3、+或*后跟?表示非贪婪匹配,即尽可能少的匹配,如*?重复任意次,但尽可能少重复;
4、 .*? 表示匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
如:a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab和ab。
$是正则表达式匹配字符串结束位置
*/
@When("^I send a GET request to \"(.*?)\" and request json:$")
public void getRequest(String path, String json) {
// List<Response> responses = new ArrayList<>();
JsonTestObject jsonTestObject = JSON.parseObject(json, JsonTestObject.class);
// String ms000001 = jsonTestObject.getMS000001();
String rb000005 = jsonTestObject.getRB000005();
List<String> list = new ArrayList();
// list.add(ms000001);
list.add(rb000005);
/* for (String obj :list ) {
// response = ApiTools.get(path,json);
responses.add(ApiTools.get(path,json));
}
for (Response response: responses){
response.getContentType();
System.out.println(response);
}*/
}
/* @When("^I send a POST request to \"(.*?)\"$")
public void postRequest(String apiPath) throws Throwable {
response = ApiTools.post(apiPath);
}*/
@When("^I send a POST request to \"(.*?)\" and request json:$")
public void postRequestWithJson(String apiPath, String json) {
response = ApiTools.post(apiPath, json);
}
@When("^I use a \"(.*?)\" file to send a POST request to \"(.*?)\"$")
public void postRequestWihtFile(String fileName, String path) {
String json = ReadTxtFile.readTxtFile(fileName);
@SuppressWarnings("unchecked")
Map<String, String> maps = (Map) JSON.parse(json);
System.out.println("这是用json类来解析json字符串");
//里面的TextArea这个例子在遍历Map时用到了Map.Entry 和 Map.entrySet() ,记得只见过Map.KeySet()和values()这两个方法,
// 于是到API中一看,Map.entrySet() 这个方法返回的是一个Set<Map.Entry<K,V>>,Map.Entry 是一个接口,他的用途是表示
// 一个映射项(里面有Key和Value),而Set<Map.Entry<K,V>>表示一个映射项的Set。
for (Map.Entry<String, String> map : maps.entrySet()) {
//maps需要是一个hashmap
// 这种遍历Map的方法可以让我们在从Map中取得关键字之后,我们不用每次重复返回到Map中取得相对的值。
String objkey = map.getKey();
// String objVal = map.getValue().toString();
// String objVal = JSON.parseObject(map.getValue()).toJSONString();
String objVal = JSON.toJSONString(map.getValue());
System.out.println("key:" + objkey);
System.out.println("请求入参value:" + objVal);
// response = ApiTools.post(path,objVal);
responses.put(objkey, ApiTools.post(path, objVal));
response = ApiTools.post(path, objVal);
System.out.println("____________________");
}
// response = ApiTools.post(path, json);
}
@Then("^the JSON response equals$")
public void assertResponseJson(String expected) {
String responseJson = response.body().asString();
assertJsonEquals(responseJson, expected);
}
@Then("^the JSON response equals json file \"(.*?)\"$")
public void theJSONResponseEqualsJsonFile(String fileName) {
System.out.println("-------------------------------------------------");
// Map<String, Response> responses = this.responses;
// String responseJson = response.body().asString();
System.out.println("-------------------------------------------------");
// System.out.println("responseJson = " + responseJson);
System.out.println("-------------------------------------------------");
String fileJson = ReadTxtFile.readTxtFile(fileName);
System.out.println("fileJson = " + fileJson);
System.out.println("-------------------------------------------------");
@SuppressWarnings("unchecked")
//JSON.parse(fileJson); json字符串转换成Json对象
Map<String, String> filemap = (Map) JSON.parse(fileJson);
for (Map.Entry<String, String> entry : filemap.entrySet()) {
for (Map.Entry<String, Response> responseEntry : responses.entrySet()) {
if (responseEntry.getKey().equals(entry.getKey())) {
// System.out.println("entry = " + JSONObject.toJSON(entry.getValue()).toString());
System.out.println("-------------------------------------------------");
assertJsonEquals(entry.getValue(), responseEntry.getValue().getBody().asString());
}
}
}
}
@Then("^the response status should be \"(\\d{3})\"$")
public void assertStatusCode(int statusCode) {
Object jsonResponse = response.getStatusCode();
MyAssert.assertEquals(jsonResponse, statusCode);
}
@Then("^the JSON response \"(.*?)\" equals \"(.*?)\"$")
public void assertEquals(String str, String expected) {
String jsonValue = ApiTools.getJsonPathValue(response, str);
MyAssert.assertEquals(jsonValue, expected);
}
@Then("^the JSON response \"(.*?)\" type should be \"(.*?)\"$")
public void assertMatch(String str, String match) {
String jsonValue = ApiTools.getJsonPathValue(response, str);
MyAssert.assertMatch(jsonValue, match);
}
@Then("^the JSON response \"(.*?)\" should be not null$")
public void assertNotNull(String str) {
String jsonValue = ApiTools.getJsonPathValue(response, str);
MyAssert.assertNotNull(jsonValue);
}
/* @Then("^the JSON response \"(.*?)\" start with \"(.*?)\"$")
public void assertStartWith(String str, String start) {
String jsonValue = ApiTools.getJsonPathValue(response, str);
MyAssert.assertStartWith(jsonValue, start);
}
@Then("^the JSON response \"(.*?)\" end with \"(.*?)\"$")
public void assertEndWith(String str, String end) {
String jsonValue = ApiTools.getJsonPathValue(response, str);
MyAssert.assertEndWith(jsonValue, end);
}*/
@Then("^the JSON response \"(.*?)\" include \"(.*?)\"$")
public void assertInclude(String str, String include) {
String jsonValue = ApiTools.getJsonPathValue(response, str);
MyAssert.assertInclude(jsonValue, include);
}
;
}
RB000005.feature
Feature: RB000005
@fullRegression
Scenario Outline:test get request
When I send a GET request to "XXXXXX"
Then the response status should be "200"
# 校验返回json的某个字段值为XXX
Then the JSON response "genericPlan" equals "false"
Examples:
| id |
| 1469513209147 |
| 1469513209148 |
@fullRegression
Scenario:test get request111
When I send a GET request to "XXXXXX"
Then the response status should be "200"
# 校验返回json的某个字段值为XXX
Then the JSON response "genericPlan" equals "false"
Then the JSON response "ehiCarrierId" equals "90121100"
Then the JSON response "carrierName" equals "Anthem Blue Cross"
@fullRegression
Scenario Outline: use examples
When I send a GET request to "XXXXXXX"
Then the response status should be "200"
Then the JSON response "<jsonPath>" equals "<value>"
Examples:
| jsonPath | value |
| genericPlan | false |
| ehiCarrierId | 90121100 |
| carrierName | Anthem Blue Cross |
@sanity
Scenario: test post request
When I send a POST request to "XXXXXXXX"
Then the response status should be "200"
And the JSON response "message" equals "success"
# 校验放回值是否是某种类型
And the JSON response "sessionId" type should be "^\d{6}$"
# 校验返回值不为空
And the JSON response "url" should be not null
# 校验是否以XX开头
Then the JSON response "message" start with "su"
# 校验是否以XX开头
Then the JSON response "message" end with "ss"
# 校验是否以XX开头
Then the JSON response "message" include "ss"
@sanity
Scenario: test post request
When I send a POST request to "XXXXX" and request json:
"""
{
"sessionId": 244636,
"agentNotes": "notepad"
}
"""
Then the response status should be "200"
And the JSON response "result" equals "success"
@sanity
Scenario: test post request
When I send a POST request to "abdc" and request json:
"""
{
"sessionId": 244636,
"agentNotes": "notepad"
}
"""
Then the response status should be "200"
# 校验返回json是否为XXX,对整个返回json的校验
Then the JSON response equals
"""
{
"result":"success"
}
"""
@unimplemented
Scenario: 返回的json直接跟某文件校验对比
When I use a "requRB000005.json" file to send a POST request to "https://idp-stg.jryzt.com/vega/core/inner/deposit"
Then the response status should be "200"
Then the JSON response equals json file "respRB000005.json"
# And the JSON response "data.application.context_data.enter_when" equals "2016/07/25 23:06:45 -0700"