测试开发栈我爱编程

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

2018-01-26  本文已影响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
接口自动化测试(一):关于接口

上一篇下一篇

猜你喜欢

热点阅读