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

时间:2016-05-27 20:53:33

标签: javascript node.js

我在不同的文件中进行了tape.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([....])单独调用每个文件。但这将重新发明轮子 - 编写我自己的测试运行器框架。

4 个答案:

答案 0 :(得分:1)

在您的控制流程中似乎需要blue-tape,通过添加promises,您可以将两个测试合并为一个,然后将每个测试结果转换为promise并链接两个promise。

test("simple test", function(t) {
    return test1();
});

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

你可以看一下bluebird,如果你想要对录像带进行pomisify。

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

答案 1 :(得分:0)

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

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

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不会退出,因此每个测试只有在前一个测试完成后才会运行。在我的脚本中每个测试文件有一行,我想这不是世界末日......

答案 2 :(得分:0)

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

<强> test1.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() ;
} ) ;

<强> test2.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';

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

答案 3 :(得分:-1)

坦率地说,您的单元测试不应该改变您的数据库。如果你想做得对,你应该完全将你的数据库与单元测试隔离开来。

除此之外:您的单元测试应该能够在任何时间以任何顺序运行而不会相互影响。如果情况并非如此,那么您就没有良好的单元测试。

您可以轻松地尝试按顺序运行测试,或者您可以正确地进行测试,投入一些时间并摆脱数据库依赖性。只有第二种解决方案是可取的。