• 0
  • 1
分享

利用空闲之余,写了第一个接口自动化测试demo, 通过读取execl中的接口测试用例,接口自动执行。(这里跟很多网上的接口自动化有点不同的是:无需再写代码,只需要从execl中增加用例,就可执行)。


这是execl的模板:

20180925113509402.png

这个模板可以很好的管理项目的各个模块,看起来也是简洁,也是颇为喜欢的~~

主要就是写了这几个类,完成了接口自动化的第一步:

2.png

在尝试写这个demo时,最大的问题困扰的我是:每个请求的参数方式(请求参数和body参数)不一致,个数不一致。怎样能用简洁的方式实现? 最终解决的办法就是:

在execl中增加参数类型判断:paramType, 如果是params,封装一个将json格式的字符串转换成map格式,如果是body, 就直接使用execl中的json格式。

好了,上代码(只是简单的实现,还没有很多处理,如果你们有幸看到,可以自己在这个基础上改进完善,我也会一直完善这个框架,嘻~~)

首先是util:

execlUtil:读取execl数据

package utils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelUtils {
    Sheet sheet = null;
    Row row = null;
    List<Map<String,String>> list = null;
    String cellData = null;
    String filePath =System.getProperty("user.dir")+"/XapiCaseData/ScooperApiTestCase.xlsx";
    String columns[] = {"caseName","caseDescription","isRun","baseURI","path","method","paramType","params"};
    Workbook wb = readExcel(filePath);
    /**
     * 获取excel的sheet的数量
     */
    public int getSheetNum(){
        return wb.getNumberOfSheets();
    }
    /**
     * 获取excel的sheet[]的名字
     */
    public String getSheetName(int i){
        return wb.getSheetName(i);
    }
    /**
     * 读取sheet里的接口用例参数:
           "caseName","caseDescription","isRun","baseURI","path","method","paramType","params"
     * @param sheetNum
     * @return List
     */
    public List<Map<String,String>> getTestData(int sheetNum) {
           //获取sheet
           sheet = wb.getSheetAt(sheetNum);
           if(wb != null){
                //用来存放表中数据
                list = new ArrayList<Map<String,String>>();
                //获取最大行数
                int rownum = sheet.getPhysicalNumberOfRows();
                //获取第一行
                row = sheet.getRow(0);
                //获取最大列数
                int colnum = row.getPhysicalNumberOfCells();
                //循环遍历各个sheets的行和列值添加到List集合
                for (int i = 1; i < rownum; i++) {
                    Map<String, String> map = new LinkedHashMap<String, String>();
                    row = sheet.getRow(i);
                    if (row != null) {
                        for (int j = 0; j < colnum; j++) {
                            cellData = (String) getCellFormatValue(row.getCell(j));
                            map.put(columns[j], cellData);
                        }
                    } else {
                        break;
                    }
                    list.add(map);
                }
            }
        return list;
    }
    //读取excel
    public static Workbook readExcel(String filePath){
        Workbook wb = null;
        if(filePath==null){
            return null;
        }
        String extString = filePath.substring(filePath.lastIndexOf("."));
        InputStream is = null;
        try {
            is = new FileInputStream(filePath);
            if(".xls".equals(extString)){
                return wb = new HSSFWorkbook(is);
            }else if(".xlsx".equals(extString)){
                return wb = new XSSFWorkbook(is);
            }else{
                return wb = null;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return wb;
    }
    public static Object getCellFormatValue(Cell cell){
        Object cellValue = null;
        if(cell!=null){
            //判断cell类型
            switch(cell.getCellType()){
                case Cell.CELL_TYPE_NUMERIC:{
                    cellValue = String.valueOf(cell.getNumericCellValue());
                    break;
                }
                case Cell.CELL_TYPE_FORMULA:{
                    //判断cell是否为日期格式
                    if(DateUtil.isCellDateFormatted(cell)){
                        //转换为日期格式YYYY-mm-dd
                        cellValue = cell.getDateCellValue();
                    }else{
                        //数字
                        cellValue = String.valueOf(cell.getNumericCellValue());
                    }
                    break;
                }
                case Cell.CELL_TYPE_STRING:{
                    cellValue = cell.getRichStringCellValue().getString();
                    break;
                }
                default:
                    cellValue = "";
            }
        }else{
            cellValue = "";
        }
        return cellValue;
    }
}

logUtil类:打印日志

package utils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LogUtils {
    //class对象
    private final Class<?> clazz;
    private Logger logger;
    public LogUtils(Class<?> clazz){
        this.clazz = clazz;
        this.logger = LogManager.getLogger(this.clazz);
    }
    public void info(String message){
        logger.info(clazz.getCanonicalName()+": "+message);
    }
    public void debug(String message){
        logger.debug(clazz.getCanonicalName()+": "+message);
    }
    public void error(String message){
        logger.error(clazz.getCanonicalName()+": "+message);
    }
    public void trace(String message){
        logger.trace(clazz.getCanonicalName()+": "+message);
    }
    public void warn(String message){
        logger.warn(clazz.getCanonicalName()+": "+message);
    }
}

getRequestValue类:获取请求值

package baseframework;
import org.json.JSONObject;
import utils.ExcelUtils;
import utils.LogUtils;
import java.util.*;
public class GetRequestValue {
    ExcelUtils excelUtils = new ExcelUtils();
    LogUtils logUtils = new LogUtils(GetRequestValue.class);
    List<Map<String, String>> list =null;
    /**
     * 获取excel的数据
     * @param sheetNum
     * @return list
     */
    public List list(int sheetNum){
        list = excelUtils.getTestData(sheetNum);
        return list;
    }
    //excel的sheet数量
    public int getSheetNum(){
        return excelUtils.getSheetNum();
    }
    public String isRun(int i){
        String isRun = list.get(i).get("isRun");
        logUtils.info("此条用例的运行状态:"+isRun);
        return isRun;
    }
    public String method(int i){
        String method = list.get(i).get("method");
        logUtils.info("发送请求方法:"+method);
        return method;
    }
    public String paramType(int i){
        String paramType = list.get(i).get("paramType");
        return paramType;
    }
    //获取excel中的:"sheetName","caseName","caseDescription","isRun","baseURI","path","Method","paramType"
    public String sheetName(int i){
        String sheetName=excelUtils.getSheetName(i) ;
        logUtils.info("***********************开始执行:" + sheetName + " 接口用例*********************");
        return sheetName;
    }
    public String caseName(int i){
        String caseName= list.get(i).get("caseName");
        logUtils.info("==============caseName:"+caseName+"==================");
        return caseName;
    }
    public String caseDescription(int i) {
        String caseDescription =list.get(i).get("caseDescription");
        logUtils.info("测试"+caseDescription);
        return caseDescription;
    }
    public String baseURI(int i){
        String baseURI = list.get(i).get("baseURI");
        logUtils.info("baseURI: "+baseURI);
        return baseURI;
    }
    public String path(int i) {
        String path =list.get(i).get("path");
        logUtils.info("path: "+path);
        return path;
    }
    /**
     * json格式的参数
     *
     */
    public String getRequestBodyParams(int i) {
        String params =list.get(i).get("params");
        logUtils.info("请求参数:\n\n"+params+"\n");
        return params;
    }
    /**
     * 将json格式的参数转换成map格式
     *
     */
    public Map getRequestParams(int i) throws Exception {
        Map<String, Object> paramsMap=null;
            //循环读取测试case
            String params = list.get(i).get("params");
            JSONObject jsonPath = new JSONObject(params);
            Stack<JSONObject> stObj = new Stack<JSONObject>();
            stObj.push(jsonPath);
            paramsMap = new HashMap<String, Object>();
            JsonToMap(stObj, paramsMap);
            return paramsMap;
    }
    /**
     * 将json格式的键值对转换成map的方法
     * @param stObj
     * @param paramsMap
     * @throws Exception
     */
    public void JsonToMap(Stack<JSONObject> stObj, Map<String, Object> paramsMap)  throws Exception {
        if(stObj == null && stObj.pop() == null){
            return ;
        }
        JSONObject json = stObj.pop();
        Iterator it = json.keys();
        while(it.hasNext()){
            String key = (String) it.next();
            //得到value的值
            Object value = json.get(key);
            //System.out.println(value);
            if(value instanceof JSONObject)
            {
                stObj.push((JSONObject)value);
                //递归遍历
                JsonToMap(stObj,paramsMap);
            }
            else {
                paramsMap.put(key, value);
            }
        }
    }
}

assertRequestValue类:判断execl中的请求参数

package baseframework;
import io.restassured.response.Response;
import java.util.Map;
public class AssertRequestValue {
    RequestConfig requestConfig =new RequestConfig();
    GetRequestValue getRequestValue = null;
    public void setGetRequestValue(GetRequestValue getRequestValue){
        this.getRequestValue=getRequestValue;
    }
    public Response assertApiParams(int i) throws Exception {
        Response response=null;
        /**
         * 判断excel表字段:isRun
         *  1、如果是Y,
         *  2、否则 不运行这条case
         */
        if(getRequestValue.isRun(i).equals("Y")){
            /**
             * 1、先判断请求参数:请求参数是params
             * 2、再判断请求方式:post or get
             *
             */
            if(getRequestValue.paramType(i).equals("params")){
                Map<String,String> params = getRequestValue.getRequestParams(i);
                if(getRequestValue.method(i).equals("post")){
                    try {
                        response= requestConfig.setPost(params,getRequestValue.path(i));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else {
                    try {
                        response=requestConfig.setGet(params,getRequestValue.path(i));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            /**
             * 1、先判断请求参数:请求参数是body
             * 2、再判断请求方式:post or get
             *
             */
            if(getRequestValue.paramType(i).equals("body")){
                String bodyParams=getRequestValue.getRequestBodyParams(i);
                if(getRequestValue.method(i).equals("get")){
                    try {
                        response=requestConfig.setGet(bodyParams,getRequestValue.path(i));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else {
                    try {
                        response= requestConfig.setPost(bodyParams,getRequestValue.path(i));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return response;
    }
}

requestConfig类:请求配置

package baseframework;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import java.util.Map;
public class RequestConfig {
    //设置请求的地址和端口号
    public void setHttpURIandPortValue(String URI, int port){
        RestAssured.baseURI =URI;
        RestAssured.port = port;
    }
    //发送get请求,参数为params
    public Response setGet(Map setParams,String URI){
        return RestAssured.given().params(setParams).when().get(URI);
    }
    //发送post请求,参数为params
    public Response setPost(Map setParams,String URI){
        return RestAssured.given().params(setParams).when().post(URI);
    }
    //发送post请求,参数为body
    public Response setPost(String setParams,String URI){
        return RestAssured.given().body(setParams).when().post(URI);
    }
    //发送get请求,参数为body
    public Response setGet(String setParams,String URI){
        return RestAssured.given().body(setParams).when().post(URI);
    }
}

最后就是跑用例的代码了,runApiExeclCase类:执行execl中的用例

package eagleweb;
import baseframework.AssertRequestValue;
import baseframework.GetRequestValue;
import baseframework.RequestConfig;
import io.restassured.response.Response;
import utils.AssertUtils;
public class RunApiExcelCase {
    public static void main(String[] args) throws Exception {
        RequestConfig requestConfig =  new RequestConfig();
        GetRequestValue getRequestValue = new GetRequestValue();
        AssertRequestValue assertRequestValue = new AssertRequestValue();
        assertRequestValue.setGetRequestValue(getRequestValue);
        AssertUtils assertUtils = new AssertUtils();
        for(int s=0;s<getRequestValue.getSheetNum();s++){
            /**
             * 获取excel的sheetName
             */
            getRequestValue.sheetName(s);
            /**
             *  循坏执行excel的接口测试用例
             *  传入参数sheetNum
             *
             */
            for(int i=0;i<getRequestValue.list(s).size();i++){
                //接口测试名i
                getRequestValue.caseName(i);
                //接口测试描述
                getRequestValue.caseDescription(i);
                //接口URI、端口
                requestConfig.setHttpURIandPortValue(getRequestValue.baseURI(i),90);
                //打印响应结果
                Response response= assertRequestValue.assertApiParams(i);
                response.prettyPrint();
                System.out.println("\n\n");
                //判断状态码是不是200
                assertUtils.statusCode200(response);
            }
        }
    }
}

这就是我写的第一个demo了,适用于平常比较普通的接口,异常和断言以及输出报告还没有加进去,后续会一直完善的。


————————————————

版权声明:本文为CSDN博主「Kitten_336368」的原创文章,遵循 CC 4.0 BY-SA 版权协议,原文链接:https://blog.csdn.net/xiaomaoxiao336368/article/details/82838587.

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 每个开发都不想写文档。当你不想写接口文档时,可以通过安装插件在 IDEA 里实现自动同步,一边写代码一边同步接口文档给你的前端、测试同学。以下内容手把手教你怎么操作(这里仅面向使用 IDEA 编辑器、遵循 Java Spring 框架注释规范的同学):首先,你需要安装一个插件IDEA 插件市场里搜索 「Apifox Helper」,这是国内一个做 API 协作管理平台的厂商(Apifox)做的插件,可以非常方便自动生成接口文档并且同步到你的项目中。这个插件可以实现代码零入侵自动生产接口文档。IDEA 安装插件:打开 IDEA > Preferences(Settings) > Pl...
            0 0 2041
            分享
          •   备受推崇的主机和 VR 游戏开发商 Ready at Dawn 将立即关闭。据Android Central报道,该开发商的母公司 Meta 今天做出了这一决定。根据报道,Meta 公司的一位发言人表示,做出这一决定是为了让公司的 Reality Labs 能够保持在新设定的预算范围内。  该发言人补充说,受影响的团队成员仍可申请 Reality Labs 的空缺职位,但目前还不清楚有多少人受到了影响。  Ready at Dawn 于 2003 年在加利福尼亚州尔湾市首次推出。该公司的首批游戏是为索尼的PlayStation Portable 游戏机制作的,包括《达斯特》(《Jax &a...
            0 0 499
            分享
          • 软件测试人员应该居安思危每当经济不好,公司业绩不好的时候,公司都可能进行裁员。首先裁的就是测试人员。因为测试人员的技术水平相对来说比较低,容易被替代,招起来也比较容易。公司往往先拿测试人员开刀。身为测试人员,虽然我们平常的工作大部分都比较安逸。但是千万不能温水煮青蛙。应该自强不息,要像开发人员一样,不断学习,提高自己的编程水平。这样就算被裁也能很快找到新的工作。测试人员应该比开发人员更熟悉业务需求测试人员的水平主要体现在测试用例的设计上。要设计出全面,覆盖广的测试用例,需要测试人员对自己所测试的项目的业务需求非常熟悉,甚至要比开发人员还要熟悉。如果是测试银行系统,通信行业,或者ERP软件。这些...
            0 0 830
            分享
          • 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。 一、了解一下HTTP与RPC1. HTTP(HyperText Transfer Protocol) 说明:超文本传输协议,是互联网上应用最为广泛的一种网络协议。优点:就是简单、直接、开发方便,利用现成的http协议进行传输。流程图:2. RPC(Remote Procedure Call)说明:远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议...
            11 11 1488
            分享
          •   2022年度软件测试行业的趋势预测:如果你也想了解更多发展趋势,那就点击下方链接填写调查问卷吧!助力测试行业发展,还能获得精美礼包哦~链接:http://vote.51testing.com/  背景  在运用Python进行开发代码过程中,会遇到变量复制备份的场景,但并没有得到预期的结果,例如下面的例子:lista = ['a', 'b', [1, 2, 3]] listb = lista.copy() lista[2].append(4)   print(lista...
            0 0 1215
            分享
      • 51testing软件测试圈微信