主要功能:
1、通过fiddler抓取请求,导出xml文件。
2、解析xml文件至excel,或者手工填写excel数据。
3、根据excel中的URL中地址生成的接口集合和feature内容模板生成各个接口的feature文件。
4、修改feature文件,指定excel中的执行数据,添加预期值。
5、执行feature文件,使用cucumber report在jenkins中执行和统计结果。
详细如下:
1、通过fiddler抓取请求,导出xml文件。
a.Filters设置Show only the following Hosts 输入10.253.11.41:41630
b.点击Actions-Run Filterset now 开始操作系统抓取请求
c.File-Export Sessions-All Sessons菜单,选择Visual Studio WebTest格式导出文件。
d.将上述文件的内容拷贝到自己的xml文件中,删除节点,保存。
e.将文件拷贝至项目的resource目录下.
文件内容:
2、解析xml文件至excel,或者手工填写excel数据。
1)ProductExcelDataTool.java类,将xml解析写入excel
public static boolean productExcelData(String xmlFileName, String excelpath) throws UnsupportedEncodingException, DocumentException {
Listrequestlist = XmlTool.getRequestList(xmlFileName);
ExcelManage em = new ExcelManage();
//判断文件是否存在
System.out.println(em.fileExist(excelpath));
//创建文件
String title[] = {"caseNo", "URL", "Method", "Params", "ContentType", "status", "success", "message", "msgCode"};
//判断sheet是否存在
System.out.println(em.sheetExist(excelpath, "sheet1"));
em.createExcel(excelpath, "sheet1", title);
//写入到excel
em.writeToExcel(excelpath, "sheet1", requestlist);
//读取excel
ReqestEntity object = new ReqestEntity();
Listlist = em.readFromExcel(excelpath, "sheet1");
for (int i = 0; i < list.size(); i++) {
ReqestEntity reqestEntity = (ReqestEntity) list.get(i);
System.out.println(reqestEntity.getCaseNo() + "||" + reqestEntity.getUrl() + "||" + reqestEntity.getMethod() + "||"
+ reqestEntity.getParams() + "||" + reqestEntity.getContentType());
}
return true;
}
public static void main(String[] args) throws UnsupportedEncodingException, DocumentException {
boolean b = productExcelData("case.xml","fiddlerData/test2.xls");
}
}
2)解析 Fiddler xml文件生成list
package fiddler.module;
import org.apache.commons.codec.binary.Base64;
import other.TestDom4j;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
/**
* Created by linyanghua on 2017/9/26.
* 解析 Fiddler xml文件
*
*/
public class XmlTool {
/**
* 将fiddler 录制xml文件解析,并返回 Request请求数据存入List中
* @param filename resource 目录下的fiddler xml文件名
* @return ListRequest请求数据
* @throws DocumentException
* @throws UnsupportedEncodingException
*/
public static ListgetRequestList(String filename) throws DocumentException, UnsupportedEncodingException {
SAXReader reader = new SAXReader();
InputStream in = TestDom4j.class.getClassLoader().getResourceAsStream(filename);
org.dom4j.Document doc = reader.read(in);
Element root = doc.getRootElement();
//Request Node
ListreqNodes = root.elements();
Listlistreq = new ArrayList<>();
//解析xml,存入ReqestEntity 的list
int i=0;
for (Element reqNode : reqNodes) {
i++;
String method = reqNode.attribute("Method").getValue();
ListreqChild = reqNode.elements();
ReqestEntity reqestEntity = new ReqestEntity();
if (method.equals("GET")) {
reqestEntity = getRequest(reqNode);
}
if (method.equals("POST") && reqChild.size() == 1) {
reqestEntity = postFormParameter(reqNode);
}
if (method.equals("POST") && (reqChild.size() == 2)) {
for (Element e : reqChild) {
if (e.getName() == "StringHttpBody") {
reqestEntity = postStringHttpBody(reqNode);
} else if (e.getName() == "FormPostHttpBody") {
reqestEntity = postFormParameter(reqNode);
}
}
}
reqestEntity.setCaseNo("case-"+i);
listreq.add(reqestEntity);
}
return listreq;
}
/**
* get 节点数据对象
*
* @param request
* @return xml中get节点数据
*/
public static ReqestEntity getRequest(Element request) {
ReqestEntity getReq = new ReqestEntity();
String url = request.attribute("Url").getValue();
ListStringParameters = request
.selectNodes("//QueryStringParameter");
Listlistparam = new ArrayList<>();
for (Element e : StringParameters) {
String name = e.attribute("Name").getValue();
String value = e.attribute("Value").getValue();
System.out.print("Name:" + name);
System.out.print("value:" + value);
Paramter paramter = new Paramter();
paramter.setName(name);
paramter.setValue(value);
listparam.add(paramter);
}
String paraStr = listAsStr(listparam);
getReq.setMethod("GET");
getReq.setUrl(url);
if (listparam.size() >= 1) {
getReq.setParams(paraStr);
}
getReq.setContentType("application/x-www-form-urlencoded");
return getReq;
}
/**
* post json 字符串时,需要对xml 中json串解密处理,返回节点数据对象
*
* @param requestNode Request节点
* @return xml中post json节点数据
* @throws UnsupportedEncodingException
*/
public static ReqestEntity postStringHttpBody(Element requestNode) throws UnsupportedEncodingException {
ReqestEntity postJsonReq = new ReqestEntity();
String url = requestNode.attribute("Url").getValue();
String stringHttpBody = requestNode
.selectSingleNode("//StringHttpBody").getText();
String paraStr = decodePostBodyJson(stringHttpBody);
postJsonReq.setMethod("POST");
postJsonReq.setUrl(url);
postJsonReq.setParams(paraStr);
postJsonReq.setContentType("application/json");
return postJsonReq;
}
/**
* post FormParameter 返回节点数据对象
*
* @param requestNode
* @return xml中postForm节点数据
* @throws UnsupportedEncodingException
*/
public static ReqestEntity postFormParameter(Element requestNode) throws UnsupportedEncodingException {
ReqestEntity postFormReq = new ReqestEntity();
String url = requestNode.attribute("Url").getValue();
ListFormParameters = requestNode
.selectNodes("child::*/child::FormPostParameter");
Listlistparam = new ArrayList<>();
for (Element e : FormParameters) {
String name = e.attribute("Name").getValue();
String value = e.attribute("Value").getValue();
System.out.print("Name:" + name);
System.out.print("value:" + value);
Paramter paramter = new Paramter();
paramter.setName(name);
paramter.setValue(value);
listparam.add(paramter);
}
String paraStr = listAsStr(listparam);
postFormReq.setMethod("POST");
postFormReq.setUrl(url);
postFormReq.setParams(paraStr);
postFormReq.setContentType("application/x-www-form-urlencoded");
return postFormReq;
}
/**
*
* @param enStr
* @return fiddler xml文件中解密json数据
* @throws UnsupportedEncodingException
*/
public static String decodePostBodyJson(String enStr) throws UnsupportedEncodingException {
String postBodyJson;
String deStr=null;
try {
deStr = new String(decodeBase64(enStr));
} catch (Exception e) {
e.printStackTrace();
}
postBodyJson = URLDecoder.decode(URLEncoder.encode(deStr, "utf-8").replace("%00", ""),"utf-8");
return postBodyJson;
}
/***
* encode by Base64
*/
public static String encodeBase64(byte[]input) throws Exception{
Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod= clazz.getMethod("encode", byte[].class);
mainMethod.setAccessible(true);
Object retObj=mainMethod.invoke(null, new Object[]{input});
return (String)retObj;
}
/***
* decode by Base64
*/
public static byte[] decodeBase64(String input) throws Exception{
Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
Method mainMethod= clazz.getMethod("decode", String.class);
mainMethod.setAccessible(true);
Object retObj=mainMethod.invoke(null, input);
return (byte[])retObj;
}
/**
* @param bytes
* @return
*/
public static String decode(final byte[] bytes) {
String str = new String(Base64.decodeBase64(bytes));
return str;
}
/**
* 二进制数据编码为BASE64字符串
*
* @param bytes
* @return
* @throws Exception
*/
public static String encode(final byte[] bytes) {
return new String(Base64.encodeBase64(bytes));
}
/**
* 将xml中的参数list转换为字符串
* @param list
* @return request 的参数字符串
*/
public static String listAsStr(Listlist){
String paraStr = "";
if (list.size()!= 0){
for (int i=0; iif (i!=list.size()-1){
paraStr =paraStr + list.get(i).getName()+"="+ list.get(i).getValue()+"&";
}else {
paraStr =paraStr + list.get(i).getName()+"="+ list.get(i).getValue();
}
}
}
return paraStr;
}
public static void main(String[] args) throws Exception {
Listreqlist = getRequestList("case.xml");
}
}
3)excel类公共方法
package fiddler.module;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
/**
* 从excel读取数据/往excel中写入 excel有表头,表头每列的内容对应实体类的属性
*
* @author nagsh
*
*/
public class ExcelManage {
private HSSFWorkbook workbook = null;
/**
* 判断文件是否存在.
* @param fileDir 文件路径
* @return
*/
public boolean fileExist(String fileDir){
boolean flag = false;
File file = new File(fileDir);
flag = file.exists();
return flag;
}
/**
* 判断文件的sheet是否存在.
* @param fileDir 文件路径
* @param sheetName 表格索引名
* @return
*/
public boolean sheetExist(String fileDir,String sheetName){
boolean flag = false;
File file = new File(fileDir);
if(file.exists()){ //文件存在
//创建workbook
try {
workbook = new HSSFWorkbook(new FileInputStream(file));
//添加Worksheet(不添加sheet时生成的xls文件打开时会报错)
HSSFSheet sheet = workbook.getSheet(sheetName);
if(sheet!=null)
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
}else{ //文件不存在
flag = false;
}
return flag;
}
/**
* 创建新excel.
* @param fileDir excel的路径
* @param sheetName 要创建的表格索引
* @param titleRow excel的第一行即表格头
*/
public void createExcel(String fileDir,String sheetName,String titleRow[]){
//创建workbook
workbook = new HSSFWorkbook();
//添加Worksheet(不添加sheet时生成的xls文件打开时会报错)
Sheet sheet1 = workbook.createSheet(sheetName);
//新建文件
FileOutputStream out = null;
try {
//添加表头
Row row = workbook.getSheet(sheetName).createRow(0); //创建第一行
for(int i = 0;i < titleRow.length;i++){
Cell cell = row.createCell(i);
cell.setCellValue(titleRow[i]);
}
out = new FileOutputStream(fileDir);
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 删除文件.
* @param fileDir 文件路径
*/
public boolean deleteExcel(String fileDir){
boolean flag = false;
File file = new File(fileDir);
// 判断目录或文件是否存在
if (!file.exists()) { // 不存在返回 false
return flag;
} else {
// 判断是否为文件
if (file.isFile()) { // 为文件时调用删除文件方法
file.delete();
flag = true;
}
}
return flag;
}
/**
* 往excel中写入.
* @param fileDir 文件路径
* @param sheetName 表格索引
* @param requestlist ReqestEntity 有9个属性,所以只需用到前5列 下标为0,1,2,3,4,5,6,7,8
*/
public void writeToExcel(String fileDir,String sheetName, Listrequestlist) {
//创建workbook
File file = new File(fileDir);
try {
workbook = new HSSFWorkbook(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//流
FileOutputStream out = null;
HSSFSheet sheet = workbook.getSheet(sheetName);
int rowCount;
for (ReqestEntity req : requestlist) {
// 获取表格的总行数
rowCount = sheet.getLastRowNum() + 1; // 需要加一
try {
Row row = sheet.createRow(rowCount); //最新要添加的一行
// 获得表头行对象
HSSFRow titleRow = sheet.getRow(0);
if (titleRow != null) {
row.createCell(0).setCellValue(req.getCaseNo());
row.createCell(1).setCellValue(req.getUrl());
row.createCell(2).setCellValue(req.getMethod());
row.createCell(3).setCellValue(req.getParams());
row.createCell(4).setCellValue(req.getContentType());
row.createCell(5).setCellValue(req.getStatus());
row.createCell(6).setCellValue(req.getSuccess());
row.createCell(7).setCellValue(req.getMessage());
row.createCell(8).setCellValue(req.getMsgCode());
}
out = new FileOutputStream(fileDir);
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 读取excel表中的数据.
*
* @param fileDir 文件路径
* @param sheetName 表格索引(EXCEL 是多表文档,所以需要输入表索引号,如sheet1)
*/
public ListreadFromExcel(String fileDir,String sheetName) {
//创建workbook
File file = new File(fileDir);
try {
workbook = new HSSFWorkbook(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Listresult = new ArrayList();
// 读取excel数据
// 获得指定的excel表
HSSFSheet sheet = workbook.getSheet(sheetName);
// 获取表格的总行数
int rowCount = sheet.getLastRowNum() + 1; // 需要加一
if (rowCount < 1) {
return result;
}
// 获取表头的列数
int columnCount = sheet.getRow(0).getLastCellNum();
// 获得表头行对象
for (int row =1;row
HSSFRow titleRow = sheet.getRow(row);
// 遍历
ReqestEntity reqestEntity = new ReqestEntity();
reqestEntity.setCaseNo(titleRow.getCell(0).toString());
reqestEntity.setUrl(titleRow.getCell(1).toString());
reqestEntity.setMethod(titleRow.getCell(2).toString());
reqestEntity.setParams(titleRow.getCell(3).toString());
reqestEntity.setContentType(titleRow.getCell(4).toString());
reqestEntity.setStatus(titleRow.getCell(5).toString());
reqestEntity.setSuccess(titleRow.getCell(6).toString());
reqestEntity.setMessage(titleRow.getCell(7).toString());
reqestEntity.setMsgCode(titleRow.getCell(8).toString());
result.add(reqestEntity);
}
rowCount =rowCount-1;
System.out.println("rowCount:"+ rowCount);
return result;
}
/**
* 获取指定文件中指定行的数据
* @param fileDir 文件路径
* @param sheetName sheet名称
* @param index 行号
* @return ReqestEntity 对应数据
* @throws Exception
*/
public static ReqestEntity getRequestData(String fileDir,String sheetName,int index) throws Exception {
ExcelManage em = new ExcelManage();
Listlist = em.readFromExcel(fileDir,sheetName);
ReqestEntity reqestEntity = null;
for (ReqestEntity req : list) {
if (Integer.parseInt(req.getCaseNo().split("-")[1].trim()) == index) {
reqestEntity = req;
break;
}
}
if (reqestEntity==null ) throw new Exception("不存在对应行数据");
System.out.println(reqestEntity.getCaseNo()+"||"+ reqestEntity.getUrl() + "||" + reqestEntity.getMethod() + "||"
+ reqestEntity.getParams()+ "||" + reqestEntity.getContentType());
return reqestEntity;
}
public static void main(String[] args) throws Exception {
ReqestEntity req= getRequestData("fiddlerData/test2.xls","sheet1",1);
//删除文件
//System.out.println(em.deleteExcel("E:/test2.xls"));
}
}
4)cookie和常量
package fiddler.module;
import com.github.restdriver.serverdriver.RestServerDriver;
import com.github.restdriver.serverdriver.http.AnyRequestModifier;
import com.github.restdriver.serverdriver.http.response.Response;
import static com.github.restdriver.serverdriver.RestServerDriver.body;
/**
* Created by linyanghua on 2017/8/15.
*/
public class Common {
//登陆
static String hostUrl="http://10.253.11.41:41630";
static String loginurl=hostUrl+"/login?params=mid=guihe";
static String loginparam="name=wuxichao&password=Abcd1234";
static String applicationContext = "application/x-www-form-urlencoded";
static String applicationJson= "application/json";
//案件地址添加
static String addCreateUrl =hostUrl+ "/address/create";
//案件操作记录详情
static String caseOperatorRecUrl = hostUrl+"/caseOperationRecords/get";
/*
function 获取cookie
param
return
*/
static String getcookie(String url,String loginparam) throws InterruptedException {
Response response = RestServerDriver.post(url, body(loginparam,applicationContext));
Thread.sleep(3000);
String cookie= response.getHeaders().get(1).toString();
cookie=cookie.split(";")[0].split(":")[1].trim();
System.out.println( "cookie>>>"+cookie);
return cookie;
}
/**
* 案件地址添加测试
* @param jsonStr
* @param header_cookie
*/
static String addressCreateTestUrl(String jsonStr,AnyRequestModifier header_cookie) throws Exception {
Response response = RestServerDriver.post(addCreateUrl, body(jsonStr, applicationJson), header_cookie);
Thread.sleep(300);
int status = response.getStatusCode();
String content = response.getContent().toString();
if (status >= 500) throw new Exception("http报500错误,请求失败");
return content;
}
/**
* 案件操作记录详情测试
* @param id
* @param header_cookie
*/
static String caseOperationRecTestUrl(String id,AnyRequestModifier header_cookie) throws Exception {
String url = caseOperatorRecUrl+"?id="+id;
Response response = RestServerDriver.get(url,header_cookie);
int status = response.getStatusCode();
if(status >= 500) try {
throw new Exception("http报500错误,请求失败");
} catch (Exception e) {
e.printStackTrace();
}
String jsonNode = response.asText();
if(!jsonNode.contains("操作成功") || !jsonNode.contains("true")) throw new Exception("调用案件操作记录详情接口,执行失败");
return jsonNode;
}
public static void main(String[] args) throws InterruptedException {
String cookie =getcookie(loginurl,loginparam);
System.out.println( "cookie>>>"+cookie);
}
}
5)实体
package fiddler.module;
/**
* Created by linyanghua on 2017/9/21.
*/
public class Paramter {
String name;
String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package fiddler.module;
import java.util.ArrayList;
import java.util.List;
/**
* Created by linyanghua on 2017/9/21.
*/
public class ReqestEntity {
String caseNo=null;
String url= null;
String method = null;
String params;
String contentType = null;
String status = null;
String success = null;
String message = null;
String msgCode = null;
String result=null;
String reponse=null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getSuccess() {
return success;
}
public void setSuccess(String success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMsgCode() {
return msgCode;
}
public void setMsgCode(String msgCode) {
this.msgCode = msgCode;
}
public String getCaseNo() {
return caseNo;
}
public void setCaseNo(String caseNo) {
this.caseNo = caseNo;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getReponse() {
return reponse;
}
public void setReponse(String reponse) {
this.reponse = reponse;
}
public ReqestEntity() {
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
}
6)生成的excel如下:
3、根据excel中的URL中地址生成的接口集合和feature内容模板生成各个接口的feature文件。
package fiddler.module;
import java.io.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Created by linyanghua on 2017/10/10.
*/
public class ProductFeatureTool {
//生成文件路径
private static String path = "E:\\xcollection\\collectioncucumbertest\\src\\test\\resources\\fiddler\\";
//template文件路径
private static String templatePath = "E:\\xcollection\\collectioncucumbertest\\src\\test\\resources\\template\\";
//文件路径+名称
private static String filenameTemp; //feature文件
//template路径 文件路径+名称
private static String templatefile; //template文件
/**
* 创建文件
* @param fileName 文件名称
* @param templateName 文件内容
* @return 是否创建成功,成功则返回true
*/
public static boolean createFile(String fileName,String templateName){
Boolean bool = false;
filenameTemp = path+fileName+".feature";//文件路径+名称+文件类型
templatefile = templatePath + templateName;//模板文件
File file = new File(filenameTemp);
try {
//如果文件不存在,则创建新的文件
if(!file.exists()){
file.createNewFile();
bool = true;
System.out.println("success create file,the file is "+filenameTemp);
//创建文件成功后,写入内容到文件里
// writeFileContent(filenameTemp, filecontent);
copyTemplate(templatefile,filenameTemp);
}
} catch (Exception e) {
e.printStackTrace();
}
return bool;
}
/**
* 向文件中写入内容
* @param filepath 文件路径与名称
* @param newstr 写入的内容
* @return
* @throws IOException
*/
public static boolean writeFileContent(String filepath,String newstr) throws IOException{
Boolean bool = false;
String filein = newstr+"\r\n";//新写入的行,换行
String temp = "";
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
FileOutputStream fos = null;
PrintWriter pw = null;
try {
File file = new File(filepath);//文件路径(包括文件名称)
//将文件读入输入流
fis = new FileInputStream(file);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
StringBuffer buffer = new StringBuffer();
//文件原有内容
for(int i=0;(temp =br.readLine())!=null;i++){
buffer.append(temp);
// 行与行之间的分隔符 相当于“\n”
buffer = buffer.append(System.getProperty("line.separator"));
}
buffer.append(filein);
fos = new FileOutputStream(file);
pw = new PrintWriter(fos);
pw.write(buffer.toString().toCharArray());
pw.flush();
bool = true;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
//不要忘记关闭
if (pw != null) {
pw.close();
}
if (fos != null) {
fos.close();
}
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (fis != null) {
fis.close();
}
}
return bool;
}
/**
* 删除文件
* @param fileName 文件名称
* @return
*/
public static boolean delFile(String fileName){
Boolean bool = false;
filenameTemp = path+fileName+".txt";
File file = new File(filenameTemp);
try {
if(file.exists()){
file.delete();
bool = true;
}
} catch (Exception e) {
// TODO: handle exception
}
return bool;
}
/**
* 读取文件内容
* @param path
* @param fileName
* @return
*/
public static String readtxtFile(String path,String fileName) {
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 {
System.out.println("找不到指定的文件");
}
} catch (Exception e) {
System.out.println("读取文件内容出错");
e.printStackTrace();
}
return String.valueOf(stringBuffer);
}
/**
* 拷贝模板内容至文件中
* @param templatePath
* @param featurePath
* @return
*/
public static boolean copyTemplate(String templatePath, String featurePath) {
File af = new File(templatePath);
File bf = new File(featurePath);
FileInputStream is = null;
FileOutputStream os = null;
if (!bf.exists()) {
try {
bf.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
is = new FileInputStream(af);
os = new FileOutputStream(bf);
byte b[] = new byte[1024];
int len;
try {
len = is.read(b);
while (len != -1) {
os.write(b, 0, len);
len = is.read(b);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (is != null) is.close();
if (os != null) os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
public static boolean createFeatureFileProc(String fileDir,String sheetName,String templateName){
ExcelManage em = new ExcelManage();
Listlist = em.readFromExcel(fileDir,sheetName);
SetfeatureNameSet = new HashSet<>();
for (ReqestEntity r : list){
String featureName =r.getUrl().split(":")[2];
featureName =featureName.replace("/","_").substring(6);
featureNameSet.add(featureName);
}
for (String fn : featureNameSet){
createFile(fn,templateName);
}
return true;
}
public static void main(String[] args) {
// String inputFilePath = "E:\\xcollection\\collectioncucumbertest\\src\\test\\resources\\template\\featuretemplate.txt";
// String outputFilePath = "E:\\xcollection\\collectioncucumbertest\\src\\test\\resources\\feature\\" + "myfile.feature";
// boolean b = copyTemplate(inputFilePath,outputFilePath);
// System.out.println("b:"+b);
createFeatureFileProc("fiddlerData/test2.xls","sheet1","featuretemplate.txt");
}
}
模板文件内容:
@tag1
Scenario Outline:请重写场景描述
# Given prepare data for url "/address/create" with case "" SQL
# | staffCode ||
When I use "fiddlerData/test2.xls" file case-"" to send request
Then the response status should be "200"
And the JSON response "$.success" equals ""
And the JSON response "$.message" equals ""
And the JSON response "$.msgCode" equals ""
And the JSON response "$.attributes" start with "null"
# And the JSON response "$.model.id" start with ""
Examples:
|index| success|message| msgCode |
|1 | true |操作成功|0000|
生成的feature文件位置:
每个feature文件的内容跟模板一致。
stepsDefines类中定义了feature的代码实现和断言:
package testcases;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.restdriver.serverdriver.RestServerDriver;
import com.github.restdriver.serverdriver.http.Header;
import com.github.restdriver.serverdriver.http.response.Response;
import com.jayway.jsonpath.JsonPath;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import static com.github.restdriver.serverdriver.RestServerDriver.body;
import static com.github.restdriver.serverdriver.RestServerDriver.header;
import static testcases.Common.hostUrl;
import fiddler.module.ExcelManage;
import fiddler.module.ReqestEntity;
import util.ReadTxtFile;import jdbc.DBIdConstant;
import jdbc.ManagedSqlUtil;
import org.junit.Assert;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
/**
* Created by linyanghua on 2017/8/28.
*/
public class StepsDefines {
Response response = null;
String paramters="";
ReqestEntity req = null;
@When("^I send a GET request to \"(.*?)\"$")
public void getRequest(String path,MapparamMap) throws InterruptedException {
String cookie =Common.getcookie(Common.loginurl,Common.loginparam);
Header header_cookie = header("Cookie",cookie);
paramters =getStringParams(paramMap);
response = RestServerDriver.get(hostUrl+path+"?"+paramters, header_cookie);
}
@When("^I send a POST request to \"(.*?)\" with text$" )
public void postRequest(String apiPath,MapparamMap) throws Throwable {
String cookie =Common.getcookie(Common.loginurl,Common.loginparam);
Header header_cookie = header("Cookie",cookie);
paramters =getStringParams(paramMap);
response = RestServerDriver.post(hostUrl+apiPath,body(paramters, Common.applicationContext), header_cookie);
}
@When("^I send a POST request to \"(.*?)\"$" )
public void postRequest(String apiPath) throws Throwable {
String cookie =Common.getcookie(Common.loginurl,Common.loginparam);
Header header_cookie = header("Cookie",cookie);
response = RestServerDriver.post(hostUrl+apiPath,header_cookie);
}
/**
* @param apiPath
* @param paramMap
* @throws InterruptedException
* @return Response
*/
@When("^I send a POST request to \"(.*?)\" with json$")
public void postRequestWithJson(String apiPath, MapparamMap) throws InterruptedException {
String cookie =Common.getcookie(Common.loginurl,Common.loginparam);
Header header_cookie = header("Cookie",cookie);
paramters =getJSONParams(paramMap);
response = RestServerDriver.post(hostUrl+apiPath,body(paramters, Common.applicationJson), header_cookie);
}
@When("^I use a \"(.*?)\" file to send a POST request to \"(.*?)\"$")
public void postRequestWihtFile(String fileName, String path) throws InterruptedException {
String cookie =Common.getcookie(Common.loginurl,Common.loginparam);
Header header_cookie = header("Cookie",cookie);
String paramters = ReadTxtFile.readtxtFile(fileName);
response = RestServerDriver.post(hostUrl+path,body(paramters, Common.applicationJson), header_cookie);
}
@Then("^the JSON response equals$")
public void assertResponseJson(String expected) {
String responseJson = response.asText();
assertJsonEquals(responseJson, expected);
}
@Then("^the JSON response equals json file \"(.*?)\"$")
public void theJSONResponseEqualsJsonFile(String fileName) {
String responseJson = response.asText();
String fileJson = ReadTxtFile.readtxtFile(fileName);
assertJsonEquals(responseJson, fileJson);
}
@Then("^the response status should be \"(\\d{3})\"$")
public void assertStatusCode(int statusCode) {
int responseStatusCode =response.getStatusCode();
Assert.assertEquals(statusCode,responseStatusCode);
}
@Then("^the JSON response \"(.*?)\" equals \"(.*?)\"$")
public void assertEquals(String str, String expected) {
String jsonValue = getJsonPathValue(response, str);
Assert.assertEquals(expected,jsonValue);
}
@Then("^the JSON response \"(.*?)\" should be not null$")
public void assertNotNull(String str) {
String jsonValue = getJsonPathValue(response, str);
Assert.assertNotNull(jsonValue);
}
@Then("^the JSON response \"(.*?)\" start with \"(.*?)\"$")
public void assertStartWith(String str, String start) {
String jsonValue = getJsonPathValue(response, str);
boolean act_start=jsonValue.startsWith(start);
Assert.assertEquals(act_start, true);
}
@Then("^the JSON response \"(.*?)\" end with \"(.*?)\"$")
public void assertEndWith(String str, String end) {
String jsonValue = getJsonPathValue(response, str);
Assert.assertEquals(jsonValue.endsWith(end),true);
}
@Then("^the JSON response \"(.*?)\" include \"(.*?)\"$")
public void assertInclude(String str, String include) {
String jsonValue = getJsonPathValue(response, str);
Assert.assertEquals(jsonValue.contains(include),true);
}
@Then("^the response model \"(.*?)\" size equals \"(.*?)\"$")
public void assertModelJsonNode(String jsonPath,int size) {
List medelJsonArray = getJsonArray(response, jsonPath);
Assert.assertEquals(size,medelJsonArray.size());
}
@Then("^the JSON response \"(.*?)\" size more than \"(.*?)\"$")
public void assertSizeMoreThan(String jsonPath,int size) {
List medelJsonArray = getJsonArray(response, jsonPath);
Assert.assertTrue(medelJsonArray.size()>size);
}
@Then("^the response jsonArraylist \"(.*?)\" equals \"(.*?)\"$")
public void assertJsonArrayList(String jsonPath,String str) {
String medelJsonArray = getJsonArray(response, jsonPath).toString().replace("\"","");
String exceptedValue=str;
Assert.assertEquals(str.equals(exceptedValue),true);
}
/**
* @param method
* @param path
* @param contentType
* @param map
* @return
* @throws Throwable
*/
@When("^I send a \"(.*?)\" request to \"(.*?)\" with contentType:\"(.*?)\"$" )
public Response sendRequestStep(String method,String path, String contentType, Mapmap)throws Throwable{
Response response = sendRequest(method, path, contentType,map);
return response;
}
/**
* @param path
* @param casename
* @param map
* @throws Throwable
*/
@Given("^prepare data for url \"([^\"]*)\" with case \"([^\"]*)\" SQL$")
public void prepareData(String path,String casename,Mapmap) throws Throwable {
if (path.equals("case/List/phone")){
InitDBTestDataFactory.initCaseListPhoneDB(map,casename);
}else if(path.equals("/caseCollection/list")){
InitDBTestDataFactory.initCaseCollectlistDB(map,casename);
}else if(path.equals("/caseCollection/list")){
InitDBTestDataFactory.initCaseCollectlistDB(map,casename);
}else if(path.equals("/caseCollection/insert")){
InitDBTestDataFactory.initCaseCollectInstertDB(map,casename);
}else if(path.equals("/caseCollection/update")){
InitDBTestDataFactory.initCaseCollectUpdateDB(map,casename);
}else if(path.equals("/caseCollection/delete")){
InitDBTestDataFactory.initCaseCollectdeleteDB(map,casename);
}else if(path.equals("/staff/save")){
InitDBTestDataFactory.initStaffSaveDB(map,casename);
}
}
/**
* @param jsonPath
* @param tableName
* @param propertiName
* @param map
* @throws Throwable
*/
@Then("^the JSON response \"([^\"]*)\" equals table \"([^\"]*)\" property \"([^\"]*)\"$")
public void theJSONResponseEqualsTable(String jsonPath, String tableName,String propertiName,Mapmap) throws Throwable {
ListlistA =selectCheckDataFromDB(tableName,map,propertiName);
ListlistB = getJsonArray(response, jsonPath);
Collections.sort(listA);
Collections.sort(listB);
Assert.assertEquals(listA.size(),listB.size());
if (listA.size()!=0){
for (int i=0;iAssert.assertEquals(listA.get(i),listB.get(i));
}
}
}
public String getWhereSelectSql(Mapmap){
Set keySet = map.keySet();
String where = "";
int i = 0;
for (Object keyName:keySet){
i++;
if (keySet.size()!=i){
where =where + keyName+"="+"\""+map.get(keyName)+"\""+" and ";
}else {
where = where + keyName+"="+"\""+map.get(keyName)+"\"";
}
}
return where;
}
public ListselectCheckDataFromDB(String table,Map map,String field1) throws SQLException{
String whereSql = getWhereSelectSql(map);
String selectSql = "select "+field1+" from "+table+" where "+whereSql+";";
ResultSet rs = ManagedSqlUtil.selectBySql(selectSql, DBIdConstant.collectonDB);
List list = new ArrayList();
while(rs.next()){
list.add(rs.getInt(0));
}
return list;
}
public void assertJsonEquals(String responseJson,String excepted){
JSONObject jsonContent = JSON.parseObject(responseJson);
JSONObject extContent = JSON.parseObject(excepted);
boolean act_succ = JsonPath.read(jsonContent,"$.success");
boolean ext_succ = JsonPath.read(extContent,"$.success");
Assert.assertEquals(act_succ, ext_succ);
String act_msg = JsonPath.read(jsonContent,"$.message");
String ext_msg = JsonPath.read(extContent,"$.message");
Assert.assertEquals(act_msg,ext_msg);
String act_msgCode = JsonPath.read(jsonContent,"$.msgCode");
String ext_msgCode = JsonPath.read(extContent,"$.msgCode");
Assert.assertEquals(act_msgCode,ext_msgCode);
String act_attr = JsonPath.read(jsonContent,"$.attributes");
String ext_attr = JsonPath.read(extContent,"$.attributes");
Assert.assertEquals(act_attr,ext_attr);
}
public String getJsonPathValue(Response response,String jsonPath){
String str="";
String responesJson = response.asText();
JSONObject jsonContent = JSON.parseObject(responesJson);
if (JsonPath.read(jsonContent,jsonPath)!=null) {
str = JsonPath.read(jsonContent,jsonPath).toString();
return str;
}else {
return "null";
}
}
// 返回JSONArray中某个字段的所有值
public List getJsonArray(Response response, String jsonPath){
String responesJson = response.asText();
JSONObject jsonContent = JSON.parseObject(responesJson);
List list = JsonPath.read(jsonContent,jsonPath);
return list;
}
/**
*
* @param map
* @return StringParams
*/
public static String getStringParams(Mapmap){
Set keySet = map.keySet();
String paramters="";
int i = 0;
for (Object keyName : keySet) {
i++;
if (map.get(keyName)!=null) {
if (keySet.size() != i) {
paramters = paramters + keyName + "=" + map.get(keyName) + "&";
} else {
paramters = paramters + keyName + "=" + map.get(keyName);
}
}
System.out.println("键名:" + paramters);
}
return paramters;
}
/**
*
* @param map
* @return JSONParams
*/
public static String getJSONParams(Mapmap){
Map jsonMap = new HashMap();
Set keySet = map.keySet();
for (Object keyName:keySet){
if(map.get(keyName)!=null){
jsonMap.put(keyName,map.get(keyName));
}
}
String paramters = JSONObject.toJSONString(jsonMap);
return paramters;
}
public Response sendRequest(String method,String path, String contentType, Mapmap) throws Throwable {
if(method=="Post"&&contentType=="json"){
response = sendPostRequestWithJson(path,map);
}else if (method=="Post"&&contentType=="form"){
response = sendPostRequest(path,map);
}else if (method=="Get"){
response = sendGetRequest(path,map);
}
return response;
}
public Response sendGetRequest(String path,MapparamMap) throws InterruptedException {
String cookie =Common.getcookie(Common.loginurl,Common.loginparam);
Header header_cookie = header("Cookie",cookie);
paramters =getStringParams(paramMap);
response = RestServerDriver.get(hostUrl+path+"?"+paramters, header_cookie);
return response;
}
public Response sendPostRequest(String apiPath,MapparamMap) throws Throwable {
String cookie =Common.getcookie(Common.loginurl,Common.loginparam);
Header header_cookie = header("Cookie",cookie);
paramters =getStringParams(paramMap);
response = RestServerDriver.post(hostUrl+apiPath,body(paramters, Common.applicationContext), header_cookie);
return response;
}
public Response sendPostRequestWithJson(String apiPath, MapparamMap) throws InterruptedException {
String cookie =Common.getcookie(Common.loginurl,Common.loginparam);
Header header_cookie = header("Cookie",cookie);
paramters =getJSONParams(paramMap);
response = RestServerDriver.post(hostUrl+apiPath,body(paramters, Common.applicationJson), header_cookie);
return response;
}
public void waitResponse(Response response) throws InterruptedException {
int i;
for ( i=0;i<5;i++){
Thread.sleep(3000);
if (response!=null){
break;
}
}
return ;
}
@When("^I use \"([^\"]*)\" file case-\"([^\"]*)\" to send request$")
public void iUseAFileToSendRequest(String fileDir,int index) throws Throwable {
String cookie = Common.getcookie(Common.loginurl, Common.loginparam);
Header header_cookie = header("Cookie", cookie);
req= ExcelManage.getRequestData(fileDir,"sheet1",index);
if (req != null) {
if (req.getMethod().equals("GET") && req.getParams() != "") {
response = RestServerDriver.get(req.getUrl() + "?" + req.getParams(), header_cookie);
}
if (req.getMethod().equals("GET") && req.getParams() == "") {
response = RestServerDriver.get(req.getUrl(), header_cookie);
}
if (req.getMethod().equals("POST") && req.getContentType().trim().equals("application/x-www-form-urlencoded")) {
response = RestServerDriver.post(req.getUrl(), body(req.getParams(), Common.applicationContext), header_cookie);
}
if (req.getMethod().equals("POST") && req.getContentType().trim().equals( "application/json")) {
response = RestServerDriver.post(req.getUrl(), body(req.getParams(), Common.applicationJson), header_cookie);
}
}
}
public static void main(String[] args) throws Throwable {
StepsDefines sd = new StepsDefines();
sd.iUseAFileToSendRequest("fiddlerData/test2.xls",1);
}
4、修改feature文件,指定excel中的执行数据,添加预期值。
index值取1,2,3,4,5,6时对应excel中的case-1,case-2,case-3,...对应的测试数据
5、执行feature文件,使用cucumber report在jenkins中执行和统计结果。
1)新建执行类AppTest ,右键run即可执行。
package testcases;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
/**
* Created by linyanghua on 2017/8/12.
*/
@RunWith(Cucumber.class)
@CucumberOptions(
features = {"classpath:feature/"},//feature文件所在目录
glue = {"testcases"},
// tags = { "@tag" },
plugin ={"pretty",
"html:target/cucumber-report/",
"json:target/cucumber-report/cucumber.json"}
)
//@CucumberOptions(plugin={"pretty", "html:target/cucumber",
// "json:target/cucumber.json", "junit:target/junit"},
// features = "classpath:feature/staffTest.feature")
public class AppTest {
}
2)集成Jenkins cucumber report 生成报告
执行类名为APPTest
2)源码库:
3)构建:
4)构建后报告:
构建后的报告:
POM依赖包:
net.masterthought
maven-cucumber-reporting
3.9.0
execution
verify
generate
collectioncucumbertest
${project.build.directory}/cucumber-html-reports
${project.build.directory}/cucumber.json
false
org.apache.maven.plugins
maven-compiler-plugin
3.5.1
1.8
dom4j
dom4j
1.6.1
net.masterthought
maven-cucumber-reporting
3.9.0
com.alibaba
fastjson
1.1.15
com.jayway.jsonpath
json-path
2.2.0
org.apache.poi
poi-ooxml
3.10-FINAL
com.h2database
h2
1.4.185
com.github.rest-driver
rest-server-driver
1.1.43
mysql
mysql-connector-java
5.1.38
org.apache.httpcomponents
httpclient
4.5.2
info.cukes
cucumber-jvm
1.2.4
pom
info.cukes
cucumber-core
1.2.4
info.cukes
cucumber-java
1.2.4
junit
junit
4.12
info.cukes
cucumber-junit
1.2.4
info.cukes
cucumber-html
0.2.3