之前写过一篇关于统计分析平台测试数据准备的文章,那时做得比较基础,只实现了利用代码导入csv格式的测试数据,然后通过人工方式来验证统计结果的正确性。 很明显,这种方式存在两个缺点:
1、数据准备需要自己构造csv文件,不够便捷。
2、验证阶段全部需要人为进行,效率有待提高。
为了解决这些问题,后续在实践中做了一些改进。
为什么有两个验证点? 这就需要先了解下项目的特性。
APM项目主要关注移动端网络性能的监控,他由三部分组成:
第一部分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文件里手工复制、粘贴、修改的一系列操作,还能减少人为的失误。基本满足了我的要求。
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劫持分析等多方面的统计分析功能。 统计方式包括多种维度,多种筛选条件,非常复杂。
这里的自动化验证方式与普通的后台接口测试类似,就不再缀述了。
个人认为,验证统计结果是否正确,很重要的一点在于测试数据的设计。如何能精确地覆盖到每个统计点,除了对业务的熟悉,还需要很强的逻辑思考能力。这方面,我也在持续的思考和改进。
本文来自网易实践者社区,经作者施红授权发布。