问题 踢开摩卡并行描述


我希望能够让我在Mocha中的所有描述语句并行启动。有人可以帮我弄明白怎么做吗?


12353
2018-02-21 03:09


起源

你为什么想做这个?从那时起,竞争条件将会很多 before/beforeEach/after/afterEach 可以按任何顺序运行,因为所有的测试都在同一个进程中运行,你的单例,相同的环境变量等都需要相同的缓存.NodeJS无论如何都是单线程的,所以我怀疑你真的会看到收益除非您正在等待延迟操作(如HTTP调用)才能完成此操作。 - David
我有大约50种不同的描述语句测试Rest API,所有测试都是相互独立的。我试图看看是否有可能立即开始执行我的所有测试,或者批量开始执行。我只是希望能够减少运行测试所需的时间。 - Fizz
还有其他测试跑步者(如Jasmine)可以支持它,但我根本不会这样做。我会在我的测试中获得自信和稍微长时间的测试,可能不会真正独立并导致假阴性,或者更糟糕的误报。 - David
说得通。感谢您的建议。 - Fizz


答案:


你不能直接用mocha做这个,因为它创建了一个it()回调列表并按顺序调用它们。 摩卡并行测试 如果您愿意将描述移动到单独的.js文件中,则可以执行此操作。为了说服自己,在某处安装它并使用short -slow调用它,以便每次都报告:

laptop:/tmp/delme$ npm install mocha-parallel-tests
laptop:/tmp/delme$ cd node_modules/mocha-parallel-tests
laptop:/tmp/delme/node_modules/mocha-parallel-tests$ ./bin/mocha-parallel-tests test/parallel/tests --timeout 10000 --slow 100

您将看到它在运行时间最长的时间内运行了三个(非常简单的)测试套件。

如果您的测试不依赖于早期测试的副作用,则可以使它们全部异步。 一个简单的方法是在描述之前启动需要一段时间的东西并使用常规的mocha设备来评估它。在这里,我创建了一堆承诺,需要一段时间才能解决,然后再次遍历测试,在.then()函数中检查它们的结果:

var expect = require("chai").expect;

var SlowTests = [
  { name: "a" , time: 250 },
  { name: "b" , time: 500 },
  { name: "c" , time: 750 },
  { name: "d" , time:1000 },
  { name: "e" , time:1250 },
  { name: "f" , time:1500 }
];

SlowTests.forEach(function (test) {
  test.promise = takeAWhile(test.time);
});

describe("SlowTests", function () {
  // mocha defaults to 2s timeout. change to 5s with: this.timeout(5000);
  SlowTests.forEach(function (test) {
    it("should pass '" + test.name + "' in around "+ test.time +" mseconds.",
       function (done) {
         test.promise.then(function (res) {
           expect(res).to.be.equal(test.time);
           done();
         }).catch(function (err) {
           done(err);
         });
       });
  });
});

function takeAWhile (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(time);
    }, time);
  });
}
(保存为 foo.js 并调用 mocha foo.js。)

 我不同意测试应主要是同步的断言。在编译指示之前和之后更容易,但是很少有一个测试使所有剩余的测试无效。所有令人沮丧的异步测试确实阻止了对网络任务的广泛测试。


6
2018-02-21 09:41



你说“我不同意测试应该主要是同步的断言。”嗯,这很好,但是 没人说这个。 我和其他人所说的是测试应该是 顺序 但“顺序”并不意味着“同步”。您显示的示例代码不是Mocha的示例 运行测试 在平行下。 - Louis
异步运行测试允许引擎并行化许多缓慢的任务,如文件或网络访问。如果您的测试本身是计算密集型的,那么它不能替代并行进程,但在我见过的大多数情况下,异步测试大大减少了测试时间 - 如果您在提交之前进行测试,那将非常轻松。 - ericP
你没有说我在之前的评论中所说的任何内容。 - Louis


摩卡不支持你想要开箱即用的东西。它按顺序运行测试。在处理未处理的异常时,这有一个很大的优势:Mocha可以确保它在当前正在运行的测试中发生。所以它归因于当前测试的例外。它当然可以支持并行测试,但它会使Mocha复杂化很多。

我倾向于同意 大卫的评论。我不会这样做。在摩卡通常运作的层面上,并行性似乎并不特别令人满意。我之前使用测试并行性的地方是在运行端到端套件的水平。例如,在Windows 8.1中针对Firefox运行套件,同时在Linux中针对Chrome运行相同的套件。


8
2018-02-21 12:30



感谢这个信息丰富的答案,upvoted! :) - mekdev
@Louis你有使用mocha处理大量测试的建议吗?例如,我们进行了1900次测试,并且仍在攀爬,因为Ember-cli的测试生成除了eslint之外的所有脚手架等。 - Mohamed El Mahallawy
@MohamedElMahallawy我最大的摩卡套房有大约350个测试。所以你所说的不是我用摩卡要解决的问题。当我运行我的Selenium测试时,我遇到了数以千计的单独测试 表现,这是基于Python的。当我手动运行测试时,我会积极地将测试次数缩小到仅与之相关的测试次数。我用 Buildbot (也是基于Python的)自动启动贯穿整个套件的构建。 - Louis


如果您正在使用业力来开始测试,您可以使用 卡玛 - 并行 在多个浏览器实例中拆分测试。它在不同的浏览器实例中并行运行规范,并且非常简单且易于安装:

npm i karma-parallel

然后将“parallel”添加到karma.conf.js中的框架列表中

module.exports = function(config) {
  config.set({
    frameworks: ['parallel', 'mocha']
  });
};

卡玛 - 并行

披露:我是作者


1
2018-01-21 19:53