背景
最近收到了一个数据下载重构的测试需求,数据指标大概有400多个,其中包含一些简单指标(数据库透传)以及复杂指标(需要计算的),测试过程需要我们将指标以csv的形式下载下来,逐一验证指标的准确性。本文将对数据下载重构项目测试过程中的测试计划和效率化方案展开介绍。
测试计划
测试过程中最大的工作量是需要逐一验证字段的准确性,纯手工验证暴露如下问题:
②. 指标多、数据量大,只能通过抽样验证,无法保证验证的全面性
基于以上两点,在测试环境,我们采用了自动化验证的方案,基于pytest框架,具体方案将在其他文章中展开,本文不做详述。
接下来将针对字段准确性环节用到的新老版本对比的自动化脚本进行详细讲解。
对比脚本方案演进
两个csv文件对比,需要将一个作为基础文件(后面统称“base文件”),另一个作为对比文件。遍历对比文件,到base文件中找到对应的记录,逐一比较对应的列值。因为顺序是随机的,所以将账户id作为对比的key值,具体步骤如下:
01
将两个csv文件转换成字典:将账户id列作为key值、其它列值作为value
02
从对比文件dict取出一行,获取key
03
去base文件的dict判断是否存在key,如果存在,取出来,计算处理+对比各个列值,如果都相等,则pass,否则,将错误信息打印出来
04
如果上一步不存在,直接打印错误信息
电脑配置:
文件量级:20W(base文件) VS 20W(对比文件)
01
单进程直接写日志
为了使运行结果看起来更加直观,第一个版本设计的时候引入了Python的日志组件loguru来打印过程数据。核心代码如下:
为了清楚了解循环进度以及准确定位,加了较多日志,可以看到,每个循环都会去写日志。运行结束大概需要40多分钟,时间略长,排查了一下发现频繁写日志文件非常影响效率,所以接下来的版本采用集中写文件替换掉了日志模块。
02
单进程汇总写日志
基于上一个版本的问题,做了两点改进:
①. 去掉了无用的日志输出
②. 将错误信息存储到error_list,运行结束之后统一将error_list写入文件,便于查看结果
代码如下:
运行结果:
运行时间大概20分钟左右,运行效率翻了一倍,但是作为线上验证环节,我们还希望更快一些,接下来我们尝试一下并发策略。
03
并发-汇总写日志
综上所述,优先选择Python的多线程方案。将对比文件通过numpy进行分块,分发给各个线程。核心代码如下:
运行结果如下:
● 使用Python第三方库numpy将对比文件的dict进行分块
● 将分块的dict以及base文件的dict分发给各个进程行后续计算
代码如下:
运行结果:
在文件大小不是特别大的情况下,加速效果明显:运行时间较之前缩短了一倍,大概10分钟以内就可以完成。
但并不是所有量级的文件对比都有这种加速效果。
受电脑资源的限制,当文件大小超过一定的体量以后(比如csv100多万条记录),每个进程都要创建自己独立的资源,进程所需内存的大小也变得很大,所以进程启动变得缓慢,甚至一个进程运行结束,另外一个进程还没有启动,效率不如预期。
04
共享内存-并发-汇总写日志
我们看一个大文件的例子:
文件量级:100W VS 100W
单个进程运行的结果:
多进程运行的结果:
它的原理是:先启动一个ManagerServer进程,这个进程是阻塞的,它监听一个socket,然后其他进程(ManagerClient)通过socket来连接到ManagerServer,实现通信。使用了manager共享内存的代码如下:
将较大的base文件的dict放入共享空间,进程无需再单独分配相关的空间,解决了资源较大的进程启动慢的问题,运行结果如下:
从运行结果可以看出,进程是并行启动运行的,运行效率较单进程和非共享内存的多进程都有了显著的提升。另外,这里也可以将base文件和对比文件同时放入共享空间,感兴趣的同学可以实践一下。
总结
在任务是计算密集型、小内存消耗的情况下,可以选用多进程提升运行效率
在任务是计算密集型、高内存消耗的情况下,可以将大块数据进行分割,如果无法分割,可以尝试共享内存的方案解决多进程启动慢的情况
多进程的情况下,频繁写日志会降低程序的运行效率,采用集中写日志可以有效缓解问题。另外,日志要尽可能的精简,去除冗余
本文主要介绍了数据下载重构项目测试计划以及效率化方面的内容,希望能给大家在日常测试中提供一些测试的思路,有不合理或者可以优化的地方欢迎交流指正。