一天又一天,随着我们不断增加测试代码,运行整个项目的测试耗时也越来越长, 2,30分钟成了家常便饭. 怎么样才能提高测试的速度,真正发挥持续集成的作用呢?并行测试!下面介绍两个我最近了解的比较cool的并行测试lib. 有这方面更好经验的同学,希望能给点意见.
[b][size=large]deep-test[/size][/b]
[url]http://github.com/qxjit/deep-test/tree/master[/url]
貌似出自ThoughtWorks同学们之手. 从readme里可以看出,这是一个十分强悍的并行测试库.以下两点功能挺诱人:
1. 只需一行配置, 便可以为每个测试Agent自动生成测试数据库(从test库dump), Agent运行完毕,自动删除相应的数据库.
2. 并行测试不仅仅能在一台机器的不同进程运行,还可以进行分布式处理(使用druby),用多台机器来同时运行测试.
一切看起来都十分好,不过,由于deep-test对rspec的版本依赖问题,我修改了很多地方,但还是没有在项目中跑起来. 以后空了再仔细研究. 有使用过的同学希望能够分享.
[b][size=large]parallel_specs[/size][/b]
[url]http://github.com/grosser/parallel_specs/tree/master[/url]
这是一个十分简单的plugin.也是我最终采用的.他的原理是使用Process.fork, 分配出一些子进程, 将所有的spec文件平均的分配到各个进程, 然后运行"script/spec"命令. 这种方式的好处就是没有任何额外的依赖. parallel_specs使用也十分简单:
首先修改database.yml:
这个TEST_ENV_NUMBER是根据并行测试的进程数来指定的. 这里,注意的是,如果并行进程数是1的话, TEST_ENV_NUMBER是"". 行进程数是2的话, TEST_ENV_NUMBER是"2".
接下来,就是为并行进程手动创建数据库, xxx_test, xxx_test2, xxx_test3......
That's all~:)现在,我们就可以使用rake来调用并行测试任务
下面是我在项目中实际测试的结果:(测试有320个*_spec.rb文件, 3429个examples)
[table]
|并行测试进程数| 测试耗时|
|1|1603 秒|
|[color=red]2[/color]|[color=red]682 秒[/color]|
|3|487 秒|
|4|405 秒|
[/table]
测试机器是扣肉双核,从结果可以很明显的看出,增加到2个并行测试进程对测试速度的提升十分明显. 由于只有两个物理运算单元,所以3,4...更多的并行对速度并没有太多的改进. 如果继续增加CPU的数量,测试速度还能得到更高的提升.
不过,使用parallel_specs存在一个问题--CI上无法做覆盖率测试. 后来想干脆CI上分成两个project来跑,但似乎这种方法太土了,而且也没有必要使用parallel_specs了. 有待研究...
[b][size=large]deep-test[/size][/b]
[url]http://github.com/qxjit/deep-test/tree/master[/url]
貌似出自ThoughtWorks同学们之手. 从readme里可以看出,这是一个十分强悍的并行测试库.以下两点功能挺诱人:
1. 只需一行配置, 便可以为每个测试Agent自动生成测试数据库(从test库dump), Agent运行完毕,自动删除相应的数据库.
DeepTest::TestTask.new "task_name" do |t|
t.listener = "DeepTest::Database::MysqlSetupListener"
end
2. 并行测试不仅仅能在一台机器的不同进程运行,还可以进行分布式处理(使用druby),用多台机器来同时运行测试.
一切看起来都十分好,不过,由于deep-test对rspec的版本依赖问题,我修改了很多地方,但还是没有在项目中跑起来. 以后空了再仔细研究. 有使用过的同学希望能够分享.
[b][size=large]parallel_specs[/size][/b]
[url]http://github.com/grosser/parallel_specs/tree/master[/url]
这是一个十分简单的plugin.也是我最终采用的.他的原理是使用Process.fork, 分配出一些子进程, 将所有的spec文件平均的分配到各个进程, 然后运行"script/spec"命令. 这种方式的好处就是没有任何额外的依赖. parallel_specs使用也十分简单:
首先修改database.yml:
test:
adapter: mysql
database: xxx_test<%= ENV['TEST_ENV_NUMBER'] %>
username: root
这个TEST_ENV_NUMBER是根据并行测试的进程数来指定的. 这里,注意的是,如果并行进程数是1的话, TEST_ENV_NUMBER是"". 行进程数是2的话, TEST_ENV_NUMBER是"2".
接下来,就是为并行进程手动创建数据库, xxx_test, xxx_test2, xxx_test3......
That's all~:)现在,我们就可以使用rake来调用并行测试任务
rake spec:parallel[1]
rake spec:parallel #(default = 2)
rake spec:parallel[3]
...
下面是我在项目中实际测试的结果:(测试有320个*_spec.rb文件, 3429个examples)
[table]
|并行测试进程数| 测试耗时|
|1|1603 秒|
|[color=red]2[/color]|[color=red]682 秒[/color]|
|3|487 秒|
|4|405 秒|
[/table]
测试机器是扣肉双核,从结果可以很明显的看出,增加到2个并行测试进程对测试速度的提升十分明显. 由于只有两个物理运算单元,所以3,4...更多的并行对速度并没有太多的改进. 如果继续增加CPU的数量,测试速度还能得到更高的提升.
不过,使用parallel_specs存在一个问题--CI上无法做覆盖率测试. 后来想干脆CI上分成两个project来跑,但似乎这种方法太土了,而且也没有必要使用parallel_specs了. 有待研究...