如何防止文件在 Node 中完成.js按顺序运行测试



我在不同的文件中进行了磁带.js测试,这些测试改变了我的数据库。

它们在单独运行时工作正常,但是当运行tape tests/**/*.js这样的所有文件时,测试会失败 - 因为第二个文件中的测试在第一个文件完成之前就开始运行并且数据库状态不正确。

如何防止 Node 在等待异步调用完成时退出文件?

我的这些想法都行不通:

function wait()  //blocks forever so the test can never finish
{
   while (!testsFinished) {;} 
}
function wait()  //returns immediately because it uses a timeout
{
   if (!testsFinished)
      setTimeout(wait, 1000);
}

能想到的唯一其他选择是编写我自己的测试文件管理器,它使用 async.series([....]) 单独调用每个文件。但那将是重新发明轮子 - 编写我自己的测试运行器框架。

似乎您的控制流中需要蓝带,通过添加承诺,您可以将两个测试合并为一个测试,然后将每个测试结果转换为承诺并将两个承诺链接在一起。

test("simple test", function(t) {
    return test1();
});
test("nested test", function(t) {
    return test1().then(function() {
         return test2();
    });
});

如果你也想把磁带搞清楚,你可以看看蓝鸟。

我希望这有所帮助,否则您可以使用另一个(更强大)的测试框架,例如摩卡

即使我按照jack.the.ripper的建议使用了promise,我认为文件仍然会退出,或者我必须编写一个调用其他文件的中央测试文件管理器,正如他的代码所示。

相反,我认为唯一的解决方案是在我的脚本中单独调用每个测试,交换这个:

tape 'server/tests/integration/**/*.js' | faucet

为此:

tape 'server/tests/integration/webservice/routes/signUpRouteTest.js' | faucet
tape 'server/tests/integration/webservice/routes/authenticateEmailConfirmRouteTest.js' | faucet
tape 'server/tests/integration/webservice/routes/authenticateEmailRejecRouteTest.js' | faucet

由于nodejs不会在异步调用挂起时退出,因此每个测试仅在前一个测试完成后运行。 我想在我的脚本中每个测试文件都有一行并不是世界末日......

这可能不建议这样做,但理论上您可以将属性添加到节点全局对象上。

测试1.js

var test = require( 'tape' ) ;
var util = require('util');
test( 'My first test file', function( assert ) {
  assert.equal( 1, 1, 'Numbers 1 and 1 are the same' ) ;
  assert.equal( 2, 2, 'Numbers 2 and 2 are the same' ) ;
  assert.equal( 3, 3, 'Numbers 3 and 3 are the same' ) ;

  myglobalvariableWithoutVarKeyword = 'shared var';
  console.log('test1 shared var= ' + util.inspect(myglobalvariableWithoutVarKeyword));  
  assert.end() ;
} ) ;

测试2.js

var test = require( 'tape' ) ;
var util = require('util');
test( 'My second test file', function( assert ) {
  assert.equal( 4, 4, 'Numbers 4 and 4 are the same' ) ;
  assert.equal( 5, 5, 'Numbers 5 and 5 are the same' ) ;
  assert.equal( 6, 6, 'Numbers 6 and 6 are the same' ) ;

  console.log('test2 shared var= ' + util.inspect(myglobalvariableWithoutVarKeyword));  
  assert.end() ;
} ) ;

输出:

 My first test file
    √ Numbers 1 and 1 are the same
    √ Numbers 2 and 2 are the same
    √ Numbers 3 and 3 are the same
    test1 shared var = 'shared var';
  My second test file
    √ Numbers 1 and 1 are the same
    √ Numbers 2 and 2 are the same
    √ Numbers 3 and 3 are the same
    test2 shared var = 'shared var';

使用这种方法,您可以测试共享变量是否已加载所有测试,然后使用 promise 运行 assert.end()。

坦率地说,单元测试不应该改变数据库。如果你想正确地做到这一点,你应该将你的数据库与单元测试完全隔离。

除此之外:你的单元测试应该能够随时以任何顺序运行,而不会相互影响。如果不是这种情况,则您没有良好的单元测试。

您可以采用简单的方法并尝试按顺序运行测试,也可以正确运行,投入一些时间并摆脱数据库依赖。只有第二种解决方案是可取的。

最新更新