背景
我是测试开发岗位,这篇文章介绍我毕业刚入职的第一个任务,优化测试用例执行的性能。
我们部门主要的业务是做数据库之间的数据同步,测试的任务就是检测在源端数据库执行的操作能否同步到备端数据库,一句话概括就是在源端数据库执行一系列 sql 测试用例,然后在备端数据库检测测试用例是否成功的在备端执行。
当前的自动化测试脚本的执行流程是:
初始化:调用公司内部的 API 生成一组(3台)虚拟机,一台作为源端数据库,一台作为备端数据库,还有一台部署公司的产品。
- 在源端执行一个测试用例
- sleep
- 在备端查询同步情况
- 走到下一个测试用例重复上述流程
当前流程存在的性能问题是大量的时间被浪费在等待操作上,全部用例跑完要花费 5 个小时。
挑战
领导要求尽量不改动自动化测试脚本,最好一套方案能让所有的自动化脚本受益。也就是说不能通过只把某个脚本修改成多线程的方式解决。
解题思路
当前业务背景下有一个很关键的特征是测试用例之间几乎没有关联性,测试用例之间不互相依赖。这样我们就可以分而治之,把测试用例分成 n 个小组,使用一个主控制程序同时启动 n 个docker 容器,每 1 个容器挂载 1 组测试用例,这样就可以让这 n 个小组的测试用例在互相隔离的环境中并行执行。
这样其实也引入了一个新的问题,脚本执行的日志都分散在各个容器里,不利于查看。所以我们需要写一个集中收集、查看日志的服务随着测试主程序启动。
优化方案
第一步
使用 Docker 构建自动化测试脚本的运行环境,并推送到公司的镜像仓库,以后直接拉取镜像即可。
第二步
基于 docker-py 这个库写一个控制 Docker 容器的主程序,主程序也运行在 Docker 容器里,把 /var/run/docker.sock 也挂载到容器的/var/run/docker.sock 就可以实现在容器内控制宿主机的 docker 守护进程。
第三步
将测试用例尽可能均匀的分散在 n 个目录下,根据目录的个数启动 n 个线程,每个线程启动一个Docker 容器开始执行测试用例,等待所有线程都结束。
第四步
编写一个 log_server 接收多个 Docker 进程的日志,重写 logging 模块的 logging.Handler ,实现输出日志的同时把日志发送到 log_server。
结果
优化前需要跑 5 个小时,优化后仅需 40 分钟