美文网首页测试开发栈我爱编程
接口自动化测试(七):数据验证专项2

接口自动化测试(七):数据验证专项2

作者: 测试开发栈 | 来源:发表于2018-01-26 09:08 被阅读151次

    上一章节给大家分享了JSON验证的思路和方法,在最后还留了几个问题,今天的内容就主要围绕实际写代码时可能遇到的问题而展开。

    疑问1:数据验证和之前的HTTP请求怎么(更好的)结合起来?

    将响应结果(HttpResponse对象或者字符串)作为参数传入即可,新建一个结果验证的ResponseChecker类,具体实现参看下面代码:

    public class ResponseChecker {
        private static Logger logger = Logger.getLogger(ResponseChecker.class);
    
        private HttpResponse response;
        public ResponseChecker (HttpResponse response){
            this.response = response;
        }
    
        public boolean codeCheck(int code){
            if(response == null){
                return false;
            }
            try {
                Assert.assertEquals(code, response.getStatusLine().getStatusCode());
                return true;
            }catch (Error e){
                e.printStackTrace();
                return false;
            }
        }
    
        public boolean dataCheck(Map<String,Object> exceptMap) throws IOException {
            if(response == null || exceptMap == null){
                return false;
            }
    
            String content = EntityUtils.toString(response.getEntity());
            logger.info("response: " + content);
    
            Map<String,Object> actualMap = parse(content, null);
    
            boolean flag = true;
            for(Map.Entry<String, Object> item : exceptMap.entrySet()){
                logger.info(item.getKey() + " 【expected】: " + item.getValue() + ",and【actual】:" + actualMap.get(item.getKey()));
                try {
                    Assert.assertEquals(item.getValue(), actualMap.get(item.getKey()));
                }catch (Error e){
                    flag = false;
                    e.printStackTrace();
                }
            }
    
            Assert.assertEquals(true,flag);//最后false就中断本次测试
            return flag;
        }
    
        //parse()方法,请参照上一章节,这里就不贴出来占版面了
        public static Map<String, Object> parse(Object json, String parent) {……}
    }
    

    注:上面的HttpResponse 参数也可以转成String传入。

    封装好了上面的ResponseChecker类,下面我们就写个测试方法将请求和验证流程跑一下,看下效果:

    @Test
    public void test3() throws IOException {
        String url = "http://api.fixer.io/latest?base=CNY";
        HttpResponse response = new HttpRequest(url).doGet();
    
        Map<String, Object> exceptMap = new HashMap<String,Object>();
    
        exceptMap.put("base", "CNY");
        exceptMap.put("date","2018-01-12");
        exceptMap.put("rates.USD", new BigDecimal(0.15478).setScale(5, RoundingMode.HALF_UP));
        exceptMap.put("rates.JPY", new BigDecimal(17.2).setScale(1, RoundingMode.HALF_UP));
    
        ResponseChecker responseChecker = new ResponseChecker(response);
        responseChecker.codeCheck(200);
        responseChecker.dataCheck(exceptMap);
    }
    

    下图是运行的效果:


    疑问2:预期数据还有其他管理方式吗?

    这个问题显而易见了,为了方便演示,所以数据都写在测试方法中,实际项目中,你可以将预期数据放在文件(txt、json、yaml、properties等等)、excel、数据库等:
    1、可以按某个规则将数据写在文件或exce中,对比的时候将数据再读出,解析成我们需要的格式即可;
    2、更推荐在数据库的处理,实际项目中,大都我们的数据来源就是在数据库(Mysql、Oracle、HBase……甚至缓存数据库像Redis等等),以Mysql为例,我们可以通过Spring + Mybatis框架将数据库的数据转成Bean(也就是POJO),然后再将bean转成Map,然后再用上面的封装的ResponseChecker来对比验证即可。

    到这一层次对代码的要求就更高了,除了Java和数据库基础,Spring、MyBatis等相关框架也需要了解及应用,不过还是那句话,根据自己的实际情况来,先实现基础的,再研究复杂的~

    注:由于这一部分涉及的内容及代码较多,在本章节就不演示和继续深入了,后面可以再起个章节来探讨。

    疑问3:既然类型不好处理,能把Map中的value全部当String处理吗?

    答案当然是肯定的,但还是得根据实际情况和测试要求来,比如我要验证的数据只需要考虑值的正确性就行,类型无关紧要,那当然转成String最省事了。如何处理?基于上面问题1中的代码,将dataCheck()方法中预期与实际数据对比时,都转成String即可(String.valueOf(obj)),关键代码如下:

    public boolean dataCheck(Map<String,Object> exceptMap) throws IOException {
        ……
        for(Map.Entry<String, Object> item : exceptMap.entrySet()){
            ……
                Assert.assertEquals(String.valueOf(item.getValue()), String.valueOf(actualMap.get(item.getKey())));
            ……
        }
        Assert.assertEquals(true,flag);//最后中断测试
        return flag;
    }
    

    疑问4:如何对比完再中断测试?

    前面章节有上机练习过的童鞋,肯定会遇到这个疑问,有时候我们的对比数据Map中包含了很多key-value对,但并不想在第一个对比不通过时就中断了测试,还想看到后面的对比情况,这时候我们如果直接用Junit或TestNG的Assert类去对比,就直接中断了,那么需要我们稍微改进一下这个Assert.assertEquals()方法,我们发现失败时抛出的Error:java.lang.AssertionError,将这个Error捕获抛出即可,看代码实现:

    private static boolean assertEquals(Object except, Object actual){
        boolean flag = true;
        try {
            Assert.assertEquals(except, actual);
        }catch (Error e){
            flag = false;
            e.printStackTrace();
        }
        return flag;
    }
    

    然后又有问题了,这样全部捕获了,最后怎么让判断测试是pass还是fail,请参看疑问1中dataCheck()方法的代码,对于循环中的每一次对比都会记录对比状态flag,最后再来一次中断测试:Assert.assertEquals(true,flag);

    疑问5:其他类型的数据如何验证?

    这里都是对JSON数据的验证,那么其他类型如何验证?上一篇文章发出去之后,有大神提过,那就在这里借用并补充下思路:
    1、text,直接验证或使用正则表达式去验证;
    2、JSON,跳过了;
    3、XML,转成JSON验证或使用XPATH验证;
    4、binary,这一类基本是文件类型,验证文件的MD5值即可;

    扩展

    上面把绝大部分可能遇到的问题,都解答了,祝大家玩的愉快~
    那么还会有问题吗?
    不知道大家有没有发现,前面的验证都是调用Assert.assertEquals()来进行equals对比,也就是完全匹配,可是我们有时候想要验证部分匹配,比如:startsWith、endsWith、contains和相似验证等,那么肿么办?这里继续挖个坑,有兴趣的童鞋可以先自己想想怎么处理这种情况,此外,面试时也可以将这个问题作为接口自动化测试的题目,考察面试者的编程基础和解决问题的能力……

    【下章节预告】:接口自动化测试(八):测试用例管理

    原文来自下方公众号,转载请联系作者,并务必保留出处。
    想第一时间看到更多原创技术好文和资料,请关注公众号:测试开发栈

    【本系列历史章节链接】
    接口自动化测试(六):数据验证专项1
    接口自动化测试(五):Http框架搭建
    接口自动化测试(四):Helloworld入门
    接口自动化测试(三):关于URL
    接口自动化测试(二):关于HTTP
    接口自动化测试(一):关于接口

    相关文章

      网友评论

      • 守望者Howard:关于结果验证我遇到一些问题,请教下。
        你这里举例的都是接口有返回数据的,如果没有呢,比如很多POST请求,实际上是做了某些操作,没有必要返回数据,这类要如何验证结果呢?
        测试开发栈:@守望者Howard 这么说吧,按数据表现通常接口可以分为2类,数据查询类和数据操作类(比如增删改操作),你说的那种可以理解为是数据操作类,增删改对应的数据表现 是在数据库体现,那接口验证的实际数据就在数据库了,而非接口返回的本身
        守望者Howard:@测试开发栈 那为了验证对应操作的的数据表现,就可能有必要单独为测试提供某些查询功能是吧?
        测试开发栈:@守望者Howard 没有必要返回,那也总会有操作吧,验证对应操作的数据表现就行了

      本文标题:接口自动化测试(七):数据验证专项2

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