简体   繁体   English

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

[英]How to prevent file from finishing in Node.js to run tests sequentially?

I've got tape.js tests in different files that alter my database. 我已经在改变我的数据库的不同文件中进行了tape.js测试。

They work fine when run individually, but when running all the files like this tape tests/**/*.js the tests fail - because tests in the second file start running before the first file has finished and the database state is incorrect. 它们在单独运行时可以正常工作,但是在运行像tape tests/**/*.js这样的所有文件时,测试将失败-因为第二个文件中的测试在第一个文件完成之前开始运行,并且数据库状态不正确。

How do I prevent Node from exiting a file while waiting for an async call to finish? 如何防止Node在等待异步调用完成时退出文件?

Neither of these ideas I had will work: 我有这些想法都行不通:

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);
}

The only other option I can think of is to write my own test file manager that uses async.series([....]) to call each file individually. 我唯一想到的另一种选择是编写自己的测试文件管理器,该管理器使用async.series([....])单独调用每个文件。 But that would be reinventing the wheel - writing my own test runner framework. 但这将重新发明轮子-编写我自己的测试运行器框架。

Seems like you need blue-tape in your control flow, by adding promises you can join the two tests into a single one, then turn each test result into a promise and chain both promises. 似乎您的控制流程中需要蓝带 ,通过添加promise,您可以将两个测试合并为一个测试,然后将每个测试结果转换为promise,并将两个promise链接起来。

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

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

you might take a look to bluebird if you want to pomisify tape as well. 如果您也想对磁带进行pomisify,则可以看看bluebird

I hope that helps, otherwise you can use another (more robust) testing framework like mocha 希望对您有所帮助,否则您可以使用其他(更强大)的测试框架,例如mocha

Even if I used promises as jack.the.ripper suggests I think the files would still exit, or I'd have to write one central test file manager that calls other files, as his code shows. 即使我将promises用作jack.the.ripper,我也认为文件仍然会退出,或者我必须编写一个中央测试文件管理器来调用其他文件,如他的代码所示。

Instead I think the only solution is to call each test individually in my script, swapping this: 相反,我认为唯一的解决方案是在脚本中单独调用每个测试,将其交换:

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

for this: 为了这:

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

Since nodejs won't exit while an async call is pending each test will run only after the previous has finished. 由于在异步调用未决期间nodejs不会退出,因此每个测试仅在前一个测试完成后才运行。 And having one line per test file in my script I guess is not the end of the world... 我的脚本中每个测试文件只有一行,我想这不是世界末日...

This is probably not advised, but theoretically you could add properties onto nodes global object. 可能不建议这样做,但是从理论上讲,您可以将属性添加到节点全局对象上。

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

Outputs: 输出:

 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';

With this approach you could test if the shared variable has loaded all the tests, and then run assert.end() using promises. 使用这种方法,您可以测试共享变量是否已加载所有测试,然后使用promises运行assert.end()。

Frankly, your unit tests shouldn't alter your database. 坦白说,您的单元测试不应更改您的数据库。 If you want to do it right, you should completely isolate your db from the unit tests. 如果您想正确执行操作,则应将数据库与单元测试完全隔离。

Besides that: Your unit tests should be able to run at any time in any order without influencing each other. 除此之外:您的单元测试应该能够在任何时间以任何顺序运行而不会相互影响。 If this isn't the case, you don't have good unit tests. 如果不是这种情况,则说明您没有良好的单元测试。

You can go the easy way and try to run the tests in order or you can do it properly, invest some time and get rid of the database dependency. 您可以采用简单的方法尝试按顺序运行测试,也可以正确地进行测试,投入一些时间并摆脱数据库依赖性。 Only the second solution is desirable. 仅第二种解决方案是可取的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM