统计分析平台自动化验证的一些实践

之前写过一篇关于统计分析平台测试数据准备的文章,那时做得比较基础,只实现了利用代码导入csv格式的测试数据,然后通过人工方式来验证统计结果的正确性。 很明显,这种方式存在两个缺点:
1、数据准备需要自己构造csv文件,不够便捷。
2、验证阶段全部需要人为进行,效率有待提高。

为了解决这些问题,后续在实践中做了一些改进。

改进

  • 基于模板自动批量生成测试数据
  • 自动化验证collector收集的数据量
  • 自动化验证接口统计的正确性


为什么有两个验证点? 这就需要先了解下项目的特性。
APM项目主要关注移动端网络性能的监控,他由三部分组成:

  • 客户端sdk,负责收集客户端的网络请求;
  • APM后台,负责对sdk上传的数据进行收集、清洗和存储;
  • Web平台,向用户展示结果

第一部分sdk上传数据,我采用了测试数据模拟的方式,两个验证点分别对应APM后台和Web平台的功能。

具体实现

一、基于模板生成测试数据

关于测试数据,一直在思考一个问题,如何能快速、便捷地批量生成,减少人为的干预。

考虑到项目收集节点,数据是以json格式上传到接口,然后进行一系列处理。我想到了事先准备一个json格式的模板文件,把测试点无关的部分写上默认值,测试点相关的部分以$+name的形式填写。然后在代码内将模板文件以字符串形式导入,并一一替换自定义的变量($+name)。替换后的模板文件就是我们需要构造的测试数据了。实现如下:

 /**
     *
     * @param count 生成测试数据的条数
     * @param testDataName json模版文件的名称
     * @param interval 测试数据的时间区间,单位是分钟。如要生成半小时内的测试数据,即为30
     * @param data 要替换的值,map中的key和模板文件中的自定义变量名必需相同
     */
    public boolean generateTestData(int count, String testDataName, int interval, Map <String, Object> data) throws Exception {

        HttpRequest httpRequest = new HttpRequestImpl(HttpRequestMethod.POST, collectUrl);

        //设置head
        Properties headProps = PropertiesLoader.loadClasspathProperties(App.class, "/head.properties", charset);
        Set<String> keys = headProps.stringPropertyNames();
        for (String k : keys) {
            String value = headProps.getProperty(k);
            httpRequest.header(k, value);
        }
        httpRequest.contentType("application/json");

        //获取body模板
        String testData = testDataTemplateCache.get(testDataName);

        //替换参数
        for (String key : data.keySet()) {
            testData = testData.replace("$" + key, StringEscapeUtils.escapeJava(data.get(key).toString()));
        }

采用这种方式,避免了之前在csv文件里手工复制、粘贴、修改的一系列操作,还能减少人为的失误。基本满足了我的要求。

二、查询Druid,验证收集到的数据量

APM sdk上传的数据,会直接往我们的Collector节点发数据,随后,数据会经历清洗、Kafka,然后存储到Druid(Druid是一个分布式的支持实时分析的数据存储系统,它的特点是数据吞吐量大;支持流式数据摄入和实时;查询灵活且快)。

为了验证在这条链路上,数据是否存在丢失、重复等现象,我会直接去druid查询结果,并和第一步中的测试数据条数进行对比。
Druid提供了HTTP REST风格的查询接口。用户对数据的查询通过HTTP请求发送到查询节点(Broker Node),查询请求的内容是以json格式来构造的。
我也采用了事先准备好查询模板,然后替换关键参数的方式用代码实现druid查询。

以下模板就是用来查询某个app下某个域名在指定时间区间内的请求总数。

{
  "queryType" : "timeseries",
  "dataSource" : "apm_mobile_online_request",
  "intervals" : ["$intervals"],
  "granularity" : "all",
  "dimension" : "app",
  "filter": {
    "type": "and",
    "fields": [
      {"dimension":"app","value":"d9b8a3788cd64ca1b3d0f39aebb6632b","type":"selector"},
      {"dimension":"host","value":"$hostname","type":"selector"}
    ]
  },
  "aggregations" : [
    {
      "type" : "longSum",
      "name" : "requestCount",
      "fieldName" : "requestCount"
    }
  ]
}

Druid返回的查询结果也是json格式。通过对结果json进行解析,提取出总数(requestCount),和第一步中上传测试数据的条数进行对比,验证数据收集数量的准确性。

Assert.assertEquals(requestCount, uploadedCount);

三、自动化验证统计接口

数据存储到druid后,APM Web平台提供了从响应时间分析、错误分析到CDN服务质量分析、DNS劫持分析等多方面的统计分析功能。 统计方式包括多种维度,多种筛选条件,非常复杂。
这里的自动化验证方式与普通的后台接口测试类似,就不再缀述了。

个人认为,验证统计结果是否正确,很重要的一点在于测试数据的设计。如何能精确地覆盖到每个统计点,除了对业务的熟悉,还需要很强的逻辑思考能力。这方面,我也在持续的思考和改进。

本文来自网易实践者社区,经作者施红授权发布。