zoukankan      html  css  js  c++  java
  • 接口自动化:HttpClient + TestNG + Java(五)

    接口自动化:HttpClient + TestNG + Java(五) - 接口测试数据驱动

    在上一篇中,我们实现了post方法请求的封装和测试,这一篇我们做测试数据的分离。

    5.1 测试数据处理思路

    5.1.1 测试数据分离

    这里我想到,我们之前的测试demo里,全都是在testNG类里去写入测试请求的相关数据。

    如果测试到达一定规模,这样去维护测试数据会当然是不行的。

    比较好的办法应该是将测试数据分离出来,通过外部文件来管理,然后读取文件驱动测试。

    这个外部文件用Excel来做会比较合适,设计如下:

    考虑用表单来驱动请求的方法,暂时写上了Get,Post,Put和Delete方法。当然其实我还没有去实现put和delete方法,后续再添加。

    表单的内容分别记录:

    • 测试用例编号
    • 测试名称
    • 协议
    • 接口地址
    • 检查点
    • 状态码
    • key1...keyN传入参数

     之前用到的url这样的不会轻易变动的数据存放到另一个property文件中去。

    5.1.2 配置数据分离

    接下来将测试中所用到的配置独立出去:

    在src/main/resource下新建config.properties文件。

    Host = https://api.apishop.net/
    testData = \src\test\resources\APIcase.xls

     主要用于存放用到的外部文件位置。

    5.2 数据读取和处理

    5.2.1 测试基类读取配置

    在项目中src/test/java下新建包com.test.api,创建类TestApi.java,写入以下内容:

    复制代码
    package com.test.api;
    
    import java.io.FileInputStream;
    import java.util.Properties;
    
    public class TestAPI {
        public Properties prop;
        public String excelPath;
        public String host; 
        
        //构造函数
        public testAPI() {
            try {
           //数据流的形式读取配置文件 prop = new Properties(); FileInputStream fis = new FileInputStream(System.getProperty("user.dir")+ "/src/main/resources/config.properties"); prop.load(fis); } catch (Exception e) { e.printStackTrace(); } host = prop.getProperty("Host"); excelPath=prop.getProperty("testData"); } }
    复制代码

    把这个类做为我们测试基类,后续在创建测试时只要继承这个类就可以了。

    5.2.2 POI读取外部Excel

    在项目中src/main/java下的test.com.utils包中,新建ExcelProcess类,写入以下代码:

    复制代码
    package com.test.utils;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.CellType;
    
    public class ExcelProcess {public static Object[][] proessExcel(String filePath,int sheetId) throws IOException{
                 
                 //数据流读入excel
                File file = new File(System.getProperty("user.dir")+filePath);
                FileInputStream fis = new FileInputStream(file);
                HSSFWorkbook wb = new HSSFWorkbook(fis);
                
                //读取特定表单并计算行列数
                HSSFSheet sheet = wb.getSheetAt(sheetId);
                int numberOfRow = sheet.getPhysicalNumberOfRows();
                int numberOfCell = sheet.getRow(0).getLastCellNum();
    
                //将表单数据处理存入dtt对象
                Object[][] dttData = new Object[numberOfRow][numberOfCell];
                for(int i=0;i<numberOfRow;i++){
                    if(null==sheet.getRow(i)||"".equals(sheet.getRow(i))){
                        continue;
                    }
                    for(int j=0;j<numberOfCell;j++) {
                        if(null==sheet.getRow(i).getCell(j)||"".equals(sheet.getRow(i).getCell(j))){
                            continue;
                        }
                        HSSFCell cell = sheet.getRow(i).getCell(j);
                        cell.setCellType(CellType.STRING);
                        dttData[i][j] = cell.getStringCellValue();
                    }
                }     
                return dttData;
            }
    }
    复制代码

    5.2.3 jsonPath处理反馈信息

    在本篇第一部分的设计中,我将每个测试的验证点写在了外部excel文件里,基本的想法是,从反馈信息内拿出相应的键值,与excel内的验证点相比较。

    所以这里我需要改造之前的JSONParser,去实现特定键值对的获取。这里我用jsonPath去实现:

    复制代码
    package com.test.utils;
    
    import com.alibaba.fastjson.JSONObject;
    import com.jayway.jsonpath.JsonPath;
    import com.jayway.jsonpath.ReadContext;
    
    import net.minidev.json.JSONArray;
    
    public class JSONParser {
        
        public boolean isResponseCorrect(JSONObject jo,String checkpoint,String passValue){
         //用jsonpath处理json,获取result中特定键值 ReadContext context = JsonPath.parse(jo); JSONArray result = context.read("$.result.."+checkpoint); String resultString = result.get(0).toString(); if(resultString.equals(passValue)){ return true; }else{ return false; } } }
    复制代码

    jsonpath本文不再赘述,感兴趣的可以去搜索一下相关教程。本段代码也只是简单的用".."去实现对result元素下的所有元素进行遍历和匹配。

    5.3 实现测试类

    5.3.1 TestNG类实现测试

    重写TestPost测试类,改写后代码如下:

    复制代码
    package com.test.api;
    
    import org.testng.annotations.Test;
    
    import com.alibaba.fastjson.JSONObject;
    import com.test.client.RestfulClient;
    import com.test.utils.ExcelProcess;
    import com.test.utils.JSONParser;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    import org.apache.http.NameValuePair;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.message.BasicNameValuePair;
    import org.testng.Assert;
    import org.testng.annotations.BeforeClass;
    
    public class TestPost extends TestAPI{
        RestfulClient client;
        JSONObject responseBody;
        int responseCode;
        String url;
        String postBody;
        Object[][] excelData;
        HashMap<String, String> hashHead;
      
      @BeforeClass
      public void setup() throws ClientProtocolException, IOException {
          //读取用例excel
          excelData = ExcelProcess.proessExcel(excelPath, 1);
          
          //实例化client
          client = new RestfulClient();      
          
          //设置好请求头部
          hashHead = new HashMap<String, String>();
          hashHead.put("Content-Type", "application/x-www-form-urlencoded");   
      }
      
      @Test
      public void testPostRequest() throws ClientProtocolException, IOException {
        //从第二行开始遍历表单,跳过表头
        for(int i=1;i<excelData.length;i++){
            //从特定位置读取测试数据
            String address = excelData[i][3].toString();
            url = host+address;
            String checkPoint = excelData[i][4].toString();
            String checkValue = excelData[i][5].toString();
            //用NameValuePair存储所有请求参数
            List<NameValuePair> keys = new ArrayList<NameValuePair>();
            for(int j=7;j<excelData[i].length-2;j=j+2){
                //因为每种请求的参数个数不确定,在这里进行非空判断
                if(excelData[i][j]==null){
                    break;
                }
                NameValuePair pair = new BasicNameValuePair(excelData[i][j].toString(),excelData[i][j+1].toString());
                keys.add(pair);             
            }
          
          //发出请求
          client.sendPost(url, keys, hashHead);
    
          responseBody = client.getBodyInJSON();
          responseCode = client.getCodeInNumber();
    
          JSONParser jParser = new JSONParser();
          boolean result = jParser.isResponseCorrect(responseBody, checkPoint, checkValue);
          
          //断言判断结果
          Assert.assertTrue(result);
          Assert.assertEquals(responseCode, 200);
        }
      }
    }
    复制代码

    测试类继承前文的TestAPI类,setup方法读取excel表单,设置好请求头部,testPostRequest发送请求并分析结果。

    5.3.2 测试结果

    用以下外部测试数据驱动测试:

    可以看到,测试用例中包含了两个不同的接口测试,测试均通过。

    注:

    在TestNG测试类里,在读取测试数据时,我采取的是读取固定位置的参数,显然这样的处理在代码健壮性上是比较差的,可以进一步改进。

    另外测试数据中的protocol我只是进行了设计,还没有真正处理。

  • 相关阅读:
    检测后缀表达式的合法性
    对表达式进行空白符预处理
    字符串替换
    中缀表达式的计算
    Linux shell编程
    Linux常用shell
    [转载]shell脚本编写规范
    [转载]Linux文件类型
    Linux的进程
    Linux进入命令行模式
  • 原文地址:https://www.cnblogs.com/ht22ht22/p/11662953.html
Copyright © 2011-2022 走看看