框架主要技术:maven+java+testng+poi+ExtentReports等
主要实现思想:
数据驱动测试,用Excel来管理数据,‘Input’ Sheet中存放输入数据,读取数据后拼成request 调用service, 拿到response后写入 ‘Output’ Sheet 即实际结果, 实际结果在与期望结果作比较,写入结果表中,测试完成后生成测试报告
1.框架主要结构
2.项目目录
3.项目搭建过程
使用的接口示例地址:https://reqres.in/
3.1准备测试案例和配置文件
src/main/config:主要配置地址config.properties
#HOST = http://10.1.1.xxx:8080/xxxx/
HOST = https://reqres.in/
apidata文件夹下新建1.xls,为接口案例
3.2工具类:
com/qa/util:
testBase读取配置文件、
copyFile:复制apidata,生成结果表
Readexcle/writeexcle:读取与写入excle表
3.3RestClient:封装接口方法
RestClient:封装了基本的post、get、delete、put方法
public class RestClient{
final static Logger Log = Logger.getLogger(RestClient.class);
/**
* 不带请求头的get方法封装
* @param url
* @return 返回响应对象
* @throws ClientProtocolException
* @throws IOException
*/
public CloseableHttpResponse get (String url) throws ClientProtocolException, IOException {
//创建一个可关闭的HttpClient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
//创建一个HttpGet的请求对象
HttpGet httpget = new HttpGet(url);
//执行请求,相当于postman上点击发送按钮,然后赋值给HttpResponse对象接收
Log.info("开始发送get请求...");
CloseableHttpResponse httpResponse = httpclient.execute(httpget);
return httpResponse;
}
/**
* 带请求头信息的get方法
* @param url
* @param headermap,键值对形式
* @return 返回响应对象
* @throws ClientProtocolException
* @throws IOException
*/
public CloseableHttpResponse get (String url,HashMap<String,String> headermap) throws ClientProtocolException, IOException {
//创建一个可关闭的HttpClient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
//创建一个HttpGet的请求对象
HttpGet httpget = new HttpGet(url);
//加载请求头到httpget对象
for(Map.Entry<String, String> entry : headermap.entrySet()) {
httpget.addHeader(entry.getKey(), entry.getValue());
}
//执行请求,相当于postman上点击发送按钮,然后赋值给HttpResponse对象接收
CloseableHttpResponse httpResponse = httpclient.execute(httpget);
Log.info("开始发送带请求头的get请求...");
return httpResponse;
}
/**
* 封装post方法
* @param url
* @param entityString,其实就是设置请求json参数
* @param headermap,带请求头
* @return 返回响应对象
* @throws ClientProtocolException
* @throws IOException
*/
public CloseableHttpResponse post (String url, String entityString, HashMap<String,String> headermap) throws ClientProtocolException, IOException {
//创建一个可关闭的HttpClient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
//创建一个HttpPost的请求对象
HttpPost httppost = new HttpPost(url);
//设置payload
httppost.setEntity(new StringEntity(entityString));
//加载请求头到httppost对象
for(Map.Entry<String, String> entry : headermap.entrySet()) {
httppost.addHeader(entry.getKey(), entry.getValue());
}
//发送post请求
CloseableHttpResponse httpResponse = httpclient.execute(httppost);
Log.info("开始发送post请求");
return httpResponse;
}
/**
* 封装 put请求方法,参数和post方法一样
* @param url
* @param entityString,这个主要是设置payload,一般来说就是json串
* @param headerMap,带请求的头信息,格式是键值对,所以这里使用hashmap
* @return 返回响应对象
* @throws ClientProtocolException
* @throws IOException
*/
public CloseableHttpResponse put(String url, String entityString, HashMap<String,String> headerMap) throws ClientProtocolException, IOException {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPut httpput = new HttpPut(url);
httpput.setEntity(new StringEntity(entityString));
for(Map.Entry<String, String> entry : headerMap.entrySet()) {
httpput.addHeader(entry.getKey(), entry.getValue());
}
//发送put请求
CloseableHttpResponse httpResponse = httpclient.execute(httpput);
return httpResponse;
}
/**
* 封装 delete请求方法,参数和get方法一样
* @param url, 接口url完整地址
* @return,返回一个response对象,方便进行得到状态码和json解析动作
* @throws ClientProtocolException
* @throws IOException
*/
public CloseableHttpResponse delete (String url) throws ClientProtocolException, IOException {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpDelete httpdel = new HttpDelete(url);
//发送delete请求
CloseableHttpResponse httpResponse = httpclient.execute(httpdel);
return httpResponse;
}
/**
* 获取响应状态码,常用来和TestBase中定义的状态码常量去测试断言使用
* @param response
* @return 返回int类型状态码
*/
public int getStatusCode (CloseableHttpResponse response) {
int statusCode = response.getStatusLine().getStatusCode();
Log.info("解析,得到响应状态码:"+ statusCode);
return statusCode;
}
/**
*
* @param response, 任何请求返回返回的响应对象
* @return, 返回响应体的json格式对象,方便接下来对JSON对象内容解析
* 接下来,一般会继续调用TestUtil类下的json解析方法得到某一个json对象的值
* @throws ParseException
* @throws IOException
*/
public JSONObject getResponseJson (CloseableHttpResponse response) throws ParseException, IOException {
Log.info("得到响应对象的String格式");
String responseString = EntityUtils.toString(response.getEntity(),"UTF-8");
JSONObject responseJson = JSON.parseObject(responseString);
Log.info("返回响应内容的JSON格式");
return responseJson;
}
}
execute类:读取excle表,按需调用post、get等方法
public class Execut extends RestClient{
String host;
static String url;
static RestClient restClient;
static CloseableHttpResponse closeableHttpResponse;
final static Logger Log = Logger.getLogger(Execut.class);
//读取excle测试案例
public List read(File file){
ReadExcel obj = new ReadExcel();
List excelList = obj.readExcel(file);
return excelList;
}
public List selectmethod(File file) throws ClientProtocolException, IOException{
TestBase tb=new TestBase();
restClient = new RestClient();
List resList=new ArrayList();//存储响应后的数据
List excelList = read(file);
for (int i = 0; i < excelList.size(); i++) {
List list = (List) excelList.get(i);
url= tb.prop.getProperty("HOST")+list.get(3);
if(list.get(4).equals("get")){
System.out.print("调用get方法");
Log.info("开始执行用例...");
closeableHttpResponse = restClient.get(url);
}else if(list.get(4).equals("post")){
System.out.print("调用post方法");
String data = (String) list.get(6);
JSONObject object = JSONObject.fromObject(data);//String转为json对象
String userJsonString = JSON.toJSONString(object);//json转json字符串
Log.info("开始执行用例...");
//准备请求头信息
HashMap<String,String> headermap = new HashMap<String,String>();
headermap.put("Content-Type", "application/json"); //这个在postman中可以查询到
//调用post
closeableHttpResponse = restClient.post(url, userJsonString, headermap);
}else if(list.get(4).equals("put")){
System.out.print("调用put方法");
String data = (String) list.get(6);
JSONObject object = JSONObject.fromObject(data);//String转为json对象
String userJsonString = JSON.toJSONString(object);//json转json字符串
Log.info("开始执行用例...");
//准备请求头信息
HashMap<String,String> headermap = new HashMap<String,String>();
headermap.put("Content-Type", "application/json"); //这个在postman中可以查询到
//调用post
closeableHttpResponse = restClient.put(url, userJsonString, headermap);
}else if(list.get(4).equals("Delete")){
System.out.print("调用Delete方法");
Log.info("开始执行用例...");
closeableHttpResponse = restClient.delete(url);
}
System.out.println();
resList.add(closeableHttpResponse);
}
return resList;
}
}
3.4src/test/java
测试类:获取响应结果,写入result表中。
public class DemoTest extends Execut{
@Test
public void testA() throws ClientProtocolException, IOException {
String path="E:\\javaworkspace\\API_AutoFrame\\apidata\\1.xls";
Execut exe1=new Execut();
WriteExcel write=new WriteExcel();//excle写入
CopyFile copy=new CopyFile();//excle复制
copy.copyFiles(path,copy.path+"\\result.xls");
RestClient restClient = new RestClient();
File file = new File(path);
List response = exe1.selectmethod(file);
List excelList = read(file);
for(int i=0;i<response.size();i++){
List list = (List) excelList.get(i);
int liststatuscode =Integer.valueOf((String) list.get(7)) ;//响应码正确值,string转integer
String type=(String) list.get(4);//请求方法
CloseableHttpResponse res = (CloseableHttpResponse)response.get(i);
int statusCode = restClient.getStatusCode(res);//获取响应码
if(res.getEntity()!=null){
String responseString = EntityUtils.toString(res.getEntity(),"UTF-8"); ////获取响应实体把响应内容存储在字符串对象
write.writeExcel(responseString,i+1, 10, copy.path+"\\result.xls");
}
if(liststatuscode==statusCode){
write.writeExcel(String.valueOf(statusCode)+"pass",i+1, 8, copy.path+"\\result.xls");
System.out.println(type+"请求,"+"返回值正确");
}else{
write.writeExcel(String.valueOf(statusCode)+"fail",i+1, 8, copy.path+"\\result.xls");
System.out.println(type+"请求,"+"返回值错误");
}
}
}
}
运行后会在result文件夹下生成result.xls结果
3.5日志生成
src/main/config配置log4j.properties
final static Logger Log = Logger.getLogger(RestClient.class);
//需要打印的日志打印出来即可
Log.info("开始发送get请求...");
3.6testng.xml配置测试用例
主要配置如下:
<test verbose="2" preserve-order="true" name="Test1">
<classes>
<class name="com.qa.tests.DemoTest"/>
</classes>
</test>
3.7测试报告的优化:
testng自身的报告太丑,受不了。
具体参考:https://blog.csdn.net/zuozewei/article/details/85011217
在项目中的配置主要有以下:
生成的报告如下:report.html
具体代码:
链接:https://pan.baidu.com/s/1p94K1A7Z_T34moiyQSUL7A
提取码:is51