美文网首页软件测试学习之路
Java实现读取Excel中的Http请求及检查点、关联API

Java实现读取Excel中的Http请求及检查点、关联API

作者: 乘风破浪的姐姐 | 来源:发表于2018-01-08 13:31 被阅读63次
    一、项目场景

    1、excel中存储各个http请求的 类型、url,参数,头部信息,检查点,关联参数


    image.png

    2、从excel中读取并发送各类http请求,并校验检查点
    3、将各请求中关联的参数,引入对应需要关联的请求链接中

    二、实现以上需求,需要使用到框架
       <!--用于读取excel-->
            <dependency>
                <groupId>com.github.crab2died</groupId>
                <artifactId>Excel4J</artifactId>
                <version>2.1.2</version>
            </dependency>
            <!--用于读取文件-->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.6</version>
            </dependency>
            <!--用于httpclient发送get,post请求-->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.4</version>
            </dependency>
            <!--用于表达式判断-->
            <dependency>
                <groupId>com.googlecode.aviator</groupId>
                <artifactId>aviator</artifactId>
                <version>3.2.0</version>
            </dependency>
            <!--用于获取json数据-->
            <dependency>
                <groupId>com.jayway.jsonpath</groupId>
                <artifactId>json-path</artifactId>
                <version>2.4.0</version>
            </dependency>
    
    三、需要用到的Utils工具类

    1、将字符串转化成Map存储。
    如:excel中的头部信息、检查点有多个时,需要拆分

    import java.util.HashMap;
    import java.util.Map;
    public class MapUtil {
        public static Map StringToMap(String str, String regx){
    
            Map<String,Object> map = null;
            if(str!=null) {
                String[] strs = str.split(regx);
                map = new HashMap<String,Object>();
                for (String s : strs) {
                    String[] ss = s.split("=");
                    map.put(ss[0], ss[1]);
                }
            }
            return  map;
        }
        public static Map StringToMap(String str){
            return StringToMap(str,";");
        }
    }
    

    2、将参数存储到Map中。
    如:excel中的关联参数,若有多个时需要拆分,且需要得到具体关联的值。

    import com.jayway.jsonpath.JsonPath;
    import java.util.HashMap;
    import java.util.Map;
    
    public class SaveParamsUtil {
        private  static  Map<String,Object> paramsMap = new HashMap<String,Object>();
        public static void saveParamsToMap(String json,String params){
            Map<String,Object> map = MapUtil.StringToMap(params);
            if(map!=null) {
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    String key = entry.getKey();
                    String val = entry.getValue().toString();
    //这里需要用到JsonPath表达式获取具体json中的值
                    Object obj = JsonPath.read(json, val);
                    paramsMap.put(key, obj.toString());
                }
            }
        }
    
        public static Object get(String key){
            return  paramsMap.get(key);
        }
    }
    

    3、正则表达式匹配工具类
    如:excel中第三个请求url中用到关联的参数

    import com.sc.bean.TestCase;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class PatternUtil {
        private static Pattern patternRule = Pattern.compile("\\$\\{(.*?)\\}");//${id}
        public static void matcherParams(TestCase testCase){
            Matcher matcher = patternRule.matcher(testCase.getUrl());
            while (matcher.find()){
                System.out.println(matcher.group());
                String key = matcher.group(1);
                String value = SaveParamsUtil.get(key).toString();
                String url = testCase.getUrl().replace(matcher.group(),value);
                testCase.setUrl(url);
                System.out.println("newurl--->"+testCase.getUrl());
            }
        }
    }
    

    4、实际json返回的结果与excel中检查点是否一致工具类
    如:excel中 $.code的实际值与期望值 1的比较

    import com.googlecode.aviator.AviatorEvaluator;
    import com.jayway.jsonpath.JsonPath;
    import java.util.HashMap;
    import java.util.Map;
    
    public class CheckPointUtil {
        public static Boolean checkPoint(String json,String checkParam){
            if(checkParam!=null && !"".equals(checkParam) && !"null".equals(checkParam)){
                Map<String,Object> map = new HashMap<String,Object>();
                String[] cParams =  checkParam.split(";");
                for(String params:cParams){
                    String[] pars = params.split("=|>|<|>=|<=|==");
                    checkParam = checkParam.replace(pars[0],"data");
                    Object obj = JsonPath.read(json,pars[0]);
                    if(obj instanceof  String){
                        checkParam =  checkParam.replace(pars[1],StrToAviatorString(pars[1]));
                        checkParam = checkParam.replace("=","==");
                    }
                    map.put("data",obj);
                    Boolean bool = (Boolean) AviatorEvaluator.execute(checkParam,map);
                    return  bool;
                }
            }
            return true;
        }
        public static String StrToAviatorString(String str){
            return  "'"+str+"'";
        }
    }
    

    5、HttpClient发送get、post请求工具类

    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.commons.io.FileUtils;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpHost;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.entity.mime.MultipartEntityBuilder;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.protocol.HTTP;
    import org.apache.http.util.EntityUtils;
    
    public class HttpUtils {
    
        private static CloseableHttpClient httpclient;
    
        static {
            PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();
            manager.setMaxTotal(200); //连接池最大并发连接数
            manager.setDefaultMaxPerRoute(200);//单路由最大并发数,路由是对maxTotal的细分
            httpclient = HttpClients.custom().setConnectionManager(manager).build();
        }
    
        /* ConnectionRequestTimeout httpclient使用连接池来管理连接,这个时间就是从连接池获取连接的超时时间,可以想象下数据库连接池
           ConnectTimeout 建立连接最大时间
           SocketTimeout 数据传输过程中数据包之间间隔的最大时间
           HttpHost 代理
         */
        private static RequestConfig config = RequestConfig.copy(RequestConfig.DEFAULT)
                 .setSocketTimeout(10000)
                 .setConnectTimeout(5000)
                 .setConnectionRequestTimeout(100).build();
                //.setProxy(new HttpHost("127.0.0.1", 8888, "http")).build();
    
        public static String doGet(String url) throws HttpClientException {
            return doGet(url, null);
        }
    
        public static String doGet(String url, Map<String, Object> header) throws HttpClientException {
            String ret = "";
            HttpGet get = new HttpGet(url);
            get.setConfig(config);
            get.addHeader(HTTP.CONTENT_ENCODING, "UTF-8");
            CloseableHttpResponse closeableHttpResponse = null;
            try {
                if (header != null) {
                    for (Map.Entry<String, Object> entry : header.entrySet()) {
                        get.setHeader(entry.getKey(), entry.getValue().toString());
                    }
                }
                closeableHttpResponse = httpclient.execute(get);
                if (closeableHttpResponse.getStatusLine().getStatusCode() == 200) {
                    ret = EntityUtils.toString(closeableHttpResponse.getEntity(), "UTF-8");
                } else {
                    throw new HttpClientException(
                            "System level error, Code=[" + closeableHttpResponse.getStatusLine().getStatusCode() + "].");
                }
            } catch (ClientProtocolException e) {
                throw new HttpClientException("HttpClient error," + e.getMessage());
            } catch (IOException e) {
                throw new HttpClientException("IO error," + e.getMessage());
            } finally {
                if (closeableHttpResponse != null) {
                    try {
                        closeableHttpResponse.close();
                    } catch (IOException e) {
                    }
                }
            }
            return ret;
        }
    
        public static String doPostString(String url, String params, String regx) throws HttpClientException {
            Map<String, Object> paramsMp =null;
            if(params!=null) {
                paramsMp = new HashMap<String, Object>();
                String[] strp = params.split(regx);
                for (int i = 0; i < strp.length; i++) {
                    String singleparms = strp[i];
                    String[] key_values = singleparms.split("=");
                    paramsMp.put(key_values[0], key_values[1]);
                }
            }
            return doPost(url, paramsMp);
        }
        
        public static String doPost(String url, Map<String, Object> params) throws HttpClientException {
            return doPost(url, params, null);
        }
    
        public static String doPost(String url, Map<String, Object> params, Map<String, Object> header)
                throws HttpClientException {
            String ret = "";
            HttpPost post = new HttpPost(url);
            post.setConfig(config);
            post.addHeader(HTTP.CONTENT_ENCODING, "UTF-8");
            CloseableHttpResponse closeableHttpResponse = null;
            HttpEntity postEntity = null;
            try {
                if (params != null) {
                    List<NameValuePair> list = new ArrayList<NameValuePair>();
                    for (Map.Entry<String, Object> entry : params.entrySet()) {
                        list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
                    }
                    postEntity = new UrlEncodedFormEntity(list,"UTF-8");
                    post.setEntity(postEntity);
                }
    
                if (header != null) {
                    for (Map.Entry<String, Object> entry : header.entrySet()) {
                        post.setHeader(entry.getKey(), entry.getValue().toString());
                    }
                }
                closeableHttpResponse = httpclient.execute(post);
                if (closeableHttpResponse.getStatusLine().getStatusCode() == 200) {
                    ret = EntityUtils.toString(closeableHttpResponse.getEntity(), "UTF-8");
                } else {
                    throw new HttpClientException(
                            "System level error, Code=[" + closeableHttpResponse.getStatusLine().getStatusCode() + "].");
                }
            } catch (ClientProtocolException e) {
                throw new HttpClientException("HttpClient error," + e.getMessage());
            } catch (IOException e) {
                throw new HttpClientException("IO error," + e.getMessage());
            } finally {
                if (postEntity != null) {
                    try {
                        EntityUtils.consume(postEntity);
                    } catch (IOException e) {
                    }
                }
                if (closeableHttpResponse != null) {
                    try {
                        closeableHttpResponse.close();
                    } catch (IOException e) {
                    }
                }
            }
            return ret;
        }
    
        public static String doPostJson(String url, String jsonParam) throws HttpClientException {
            return doPostJson(url, jsonParam, null);
        }
    
        public static String doPostJson(String url, String jsonParam, Map<String, Object> header)
                throws HttpClientException {
            String ret = "";
            HttpPost post = new HttpPost(url);
            post.setConfig(config);
            post.addHeader(HTTP.CONTENT_ENCODING, "UTF-8");
            CloseableHttpResponse closeableHttpResponse = null;
            StringEntity postEntity = null;
            try {
                if (jsonParam != null) {
                    postEntity = new StringEntity(jsonParam, "utf-8"); 
                    postEntity.setContentEncoding("UTF-8");
                    postEntity.setContentType("application/json");
                    post.setEntity(postEntity);
                }
    
                if (header != null) {
                    for (Map.Entry<String, Object> entry : header.entrySet()) {
                        post.setHeader(entry.getKey(), entry.getValue().toString());
                    }
                }
                closeableHttpResponse = httpclient.execute(post);
                if (closeableHttpResponse.getStatusLine().getStatusCode() == 200) {
                    ret = EntityUtils.toString(closeableHttpResponse.getEntity(), "UTF-8");
                } else {
                    throw new HttpClientException(
                            "System level error, Code=[" + closeableHttpResponse.getStatusLine().getStatusCode() + "].");
                }
            } catch (ClientProtocolException e) {
                throw new HttpClientException("HttpClient error," + e.getMessage());
            } catch (IOException e) {
                throw new HttpClientException("IO error," + e.getMessage());
            } finally {
                if (postEntity != null) {
                    try {
                        EntityUtils.consume(postEntity);
                    } catch (IOException e) {
                    }
                }
                if (closeableHttpResponse != null) {
                    try {
                        closeableHttpResponse.close();
                    } catch (IOException e) {
                    }
                }
            }
            return ret;
        }
    }
    定义自己的异常类:
    public class HttpClientException extends Exception{
        private static final long serialVersionUID = 2206587260745140347L;
        public HttpClientException(String msg) {
            super(msg);
        }
    }
    
    四、excel中的各参数转化成javabean
    import com.github.crab2died.annotation.ExcelField;
    
    public class TestCase {
        
        @ExcelField(title = "类型")
        private String type;
        
        @ExcelField(title = "地址")
        private String url;
        
        @ExcelField(title = "参数")
        private String params;
        
        @ExcelField(title = "头部",order=2)
        private String header;
        
        @ExcelField(title = "测试结果", order=1)
        private String result;
        
        @ExcelField(title = "检查点")
        private String checkP;
        
        @ExcelField(title = "关联")
        private String correlation;
    
    
        public String getCheckP() {
            return checkP;
        }
    
        public void setCheckP(String checkP) {
            this.checkP = checkP;
        }
    
        public String getCorrelation() {
            return correlation;
        }
    
        public void setCorrelation(String correlation) {
            this.correlation = correlation;
        }
    
        public String getResult() {
            return result;
        }
    
        public void setResult(String result) {
            this.result = result;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public String getParams() {
            return params;
        }
    
        public void setParams(String params) {
            this.params = params;
        }
    
        public String getHeader() {
            return header;
        }
    
        public void setHeader(String header) {
            this.header = header;
        }
    
        @Override
        public String toString() {
            return "TestCase{" +
                    "type='" + type + '\'' +
                    ", url='" + url + '\'' +
                    ", params='" + params + '\'' +
                    ", header='" + header + '\'' +
                    ", result='" + result + '\'' +
                    ", checkP='" + checkP + '\'' +
                    ", correlation='" + correlation + '\'' +
                    '}';
        }
    }
    
    五、测试类

    1、通过github.Excel4J包中的ExcelUtils 读取excel,返回List
    遍历List集合,集合中的每一个对象都是 TestCase bean
    2、遍历List的过程中,判断读取excel中type请求是get还是post
    如果是get,就调用已封装好的HttpUtils中的doGet方法,需要传get请求需要的url,头部信息
    如果是post,就调用已封装好的HttpUtils中的doPost方法,需要传get请求需要的url,参数,头部信息
    因为在Excel中参数、头部信息都是以字符串的形式存储的,所以需要将参数,头部信息字符串转化成Map对象才行。
    所以,这里封装了字符串转Map的工具类MapUtil,方法名为:StringToMap,这里需要传一个分割符的参数,为了方便后续使用,重载StringToMap方法,传递了默认的分割符“;”。
    3、将get/post的请求返回结果,存储在某个变量中responseJson。
    4、检查responseJson返回的code的值,是否与excel中检查点中code的值是否一致。
    excel中“$.code=1”,先要得到excel中检查点的值,如果是多个,需要分割一下,结果为一个数组1。
    因为数组1中的每个元素,=号左侧是Jsonpath表达式,=号右侧是具体的值,所以需要继续分隔,结果为一个数组2
    分隔完成后,数组2中,第一个元素即为jsonpath表达式,这里需要将整个参数字符串中的第一个元素替化成 data
    用JsonPath.read(responseJson,数组2的第一个元素),返回一个具体的值
    判断上述返回的值是否为String类型,如果是,则需要将数组2的第二个值转化成字符串,且字符串相比较要用==,所以需要将参数中=替换成==
    将data作为key,JsonPath.read返回的值作为 value,放入Map中
    使用AviatorEvaluator.exec(params,map),返回结果为bool类型。
    5、关联:
    首先,需要查看遍历的List集合的结果中,是否存在需要接受关联参数的请求。
    这里要用到Pattern正规匹配${(.*?)}作为一个匹配的规则,这里同jmeter中正则表达式匹配
    在excel的url中通过上述匹配规则循环查看是否有需要匹配的url
    如果有匹配,则返回一个group,这里group得到的是${id}
    通过group(n)得到具体要关联的参数为id
    将excel中关联的参数id的值已转存到map中
    这里直接可调用该map,key为group(n),即可得到对应的id的value
    将url中的参数替换成该id对应的value,得到一个新的url
    重新为TestCase设置url,后续http发送请求时,即可得到一个完整url

    import com.github.crab2died.ExcelUtils;
    import com.sc.bean.TestCase;
    import com.sc.http.HttpUtils;
    import com.sc.util.CheckPointUtil;
    import com.sc.util.MapUtil;
    import com.sc.util.PatternUtil;
    import com.sc.util.SaveParamsUtil;
    import java.io.File;
    import java.util.List;
    
    public class ApiTest {
        public static void main(String[] args) throws Exception {
            String path = System.getProperty("user.dir")+ File.separator+"data"+File.separator+"apitest.xlsx";
    //通过github.Excel4J包中的ExcelUtils 读取excel,返回List
            List<TestCase> list = ExcelUtils.getInstance().readExcel2Objects(path,TestCase.class);
            if(list!=null){
                for(TestCase testCase : list){
                    PatternUtil.matcherParams(testCase);
                    String responseJson =null;
                    if("get".equals(testCase.getType())){
                        responseJson = HttpUtils.doGet(testCase.getUrl(), MapUtil.StringToMap(testCase.getHeader()));
                    }else if("post".equals(testCase.getType())){
                        responseJson = HttpUtils.doPost(testCase.getUrl(), MapUtil.StringToMap(testCase.getParams(),"&"),MapUtil.StringToMap(testCase.getHeader()));
                    }
                   Boolean checkFlag =  CheckPointUtil.checkPoint(responseJson,testCase.getCheckP());
                    System.out.println("checkFlag="+checkFlag);
                    if(checkFlag){
                        SaveParamsUtil.saveParamsToMap(responseJson,testCase.getCorrelation());
                    }
                    System.out.println(responseJson);
                }
            }
    
        }
    }
    
    六、输出结果
    checkFlag=true
    {"msg":"登录成功","uid":"E2BBEDC09FAA4406B8D85C96DF6281CF","code":"1"}
    checkFlag=true
    {"msg":"登录成功","uid":"E2BBEDC09FAA4406B8D85C96DF6281CF","code":"1"}
    ${id}
    newurl--->http://www.baidu.com?pid=E2BBEDC09FAA4406B8D85C96DF6281CF
    checkFlag=true
    <!DOCTYPE html>
    <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta ......
    

    相关文章

      网友评论

        本文标题:Java实现读取Excel中的Http请求及检查点、关联API

        本文链接:https://www.haomeiwen.com/subject/pvbmnxtx.html