【问题标题】:How to execute Rake tasks in parallel如何并行执行 Rake 任务
【发布时间】:2018-06-08 17:42:39
【问题描述】:

我有黄瓜测试可以同时在多个设备和模拟器上运行。虽然这我能够在 jenkins 中使用多个作业并将其参数化,但我不认为这是最好的方法,因为将来我们可以添加更多设备,我不想在 jenkins 中有无休止的工作。

虽然我尝试使用 rake 任务,但我发现它按顺序执行而不是并行执行

这是两个 rake 任务:

def run_cucumber(profile)
  Cucumber::Rake::Task.new do |t|
    t.profile = profile
  end
  Rake::MultiTask[:cucumber].invoke
end

task 'Device1' do |t|
  run_cucumber('MotoZ2Play')
end
task 'Device2' do |t|
  run_cucumber('MotoG5Plus')
end

这就是我使用multi task 启动Parallel rake 的方式

multitask 'build_parallel' => ['Device1', 'Device2']

这似乎又不是并行执行,而是按顺序执行。

我尝试使用代码实现并行测试 gem:

Parallel.map([:Device1,:Device2,:Device3,:Device4,:Device5]) {|task| Rake::Task[task].invoke }

但这似乎在我的黄瓜功能文件中执行随机场景,我们希望场景按照我们编写的顺序执行。

如何实现并行 rake 任务?

更新:

通过使用解决了它 Parallel.each 而不是 Parallel.map

【问题讨论】:

  • 老实说,我迷路了。 “并行”和“按我们编写的顺序”不能同时实现,这些目标相互矛盾。
  • 我猜你弄错了,按照我们写的顺序,我不是说“按照我们希望它运行的顺序”,而是指一组场景(测试用例)执行一个并行所有设备中的一个。例如:我在两个 rake X 和 Y 中有测试用例 A、B、C、D、E,我希望这些 X 和 Y 并行运行,执行 A、B、C、D、E 而不是 E、B, C、A、D
  • 这个问题有点误导,因为您已经知道如何并行运行 rake 任务。如果您可以从单个 ruby​​ 线程创建多个设备实例,那么您可以让每个测试用例为每个设备并行运行其代码.. 如果有意义的话,您不一定需要并行运行整个 rake 任务
  • @maxpleaner 这实际上让我可以使用parallel.each([:Device1, :Device2]) 而不是parallel.map,从而根据需要跨设备生成实例。谢谢。得到它的工作:)
  • 在这里添加一些额外的想法。在 Jenkins 中,不确定是哪个版本引入了它,但您现在可以在节点上运行并行任务。这意味着您正在使用 1 个执行程序在该执行程序的节点上运行多个线程。当然,您需要注意您正在运行的任务数量,因为您可能会使执行程序超载。另一种选择可能是让 Jenkins 作业在不同的从属设备上启动 x 个作业,比如 AWS 中的 EC2 实例,每个实例都有自己定义的配置。

标签: ruby cucumber rake


【解决方案1】:

有一个名为 parallel_tests https://github.com/grosser/parallel_tests 的 gem,它允许您创建自定义 rake 任务并并行运行它们。 您还可以指定要使用的 CPU 数量。

下面是我刚刚做的一些简单示例:

namespace :my_task do
  task :a => :environment do
    100.times {
      puts "A"
    }
  end

  task :b => :environment do
    100.times {
      puts "B"
    }
  end

  task :c => :environment do
    Rake::Task["my_task:a"].execute
    Rake::Task["my_task:b"].execute
  end
end

并且输出类似于:


B
B
B
B
A
A
B
B
B
B
B
B
B
B
B
B
A
A
A
A
A
A
...

希望对你有帮助。

干杯

【讨论】:

  • 谢谢!应该试试这个。这似乎是更合适的解决方案,不再严重依赖外部库
  • 是的,基本上它曾经用于加速测试套件,但作者为在其他一些情况下使用它留下了空间,例如这种情况。它在几个方面对我们都有好处。
【解决方案2】:

最好的解决方案是使用drake gem,它是rake 的一个分支,增加了并发支持。我不知道为什么multitask 对您不起作用,但主要问题是您无法指定要运行 Rakefile 的并发量。使用 drake,您可以通过 -j 选项。类似于make 的 -j 选项。

安装方式:

 gem install drake

假设你有一个像这样的 Rakefile:

task :a do
  sleep 5
  puts "a"
end

如果您运行drake -j2,那么它将以 2 的并发运行,因此“a”和“b”将在 5 秒后同时打印。

但是,如果您运行 drake(或 drake -j1),那么您将在 5 秒后只看到“a”,然后在再过 5 秒后看到“b”。

Drake 不再维护,但它仍然很好用。我已经使用它 8 年来开发 Phusion Passenger。

【讨论】:

  • 谢谢!我很快就会试试这个!
猜你喜欢
  • 2021-05-15
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 2016-02-22
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多