この質問は、NodeJSのMochaテストフレームワークに関連しています。
デフォルトの動作は、すべてのテストを開始してから、非同期コールバックが処理されると処理するようです。
非同期テストを実行する場合、各テストを実行しますafter前の非同期部分が呼び出されました。
これどうやってするの?
ポイントは、「構造化されたコードが構造化された順序で実行される」ほどではありません(驚く!)-@chrisdewが示唆するように、非同期テストの戻り順序は保証できません。問題を再現するには同期実行)チェーンのさらに下にあるテスト---(保証はできません非同期テストで設定された必要な条件は、実行時に準備が整います。
したがって、最初のテストで特定の条件(ログイントークンなど)を設定する必要がある場合は、続行する前にこれらの条件を設定するbefore()
などのフックを使用する必要があります。
ブロックで依存テストをラップし、それらに対してasyncbefore
フックを実行します(beforeブロックの「完了」に注意してください):
var someCondition = false
// ... your Async tests setting conditions go up here...
describe('is dependent on someCondition', function(){
// Polls `someCondition` every 1s
var check = function(done) {
if (someCondition) done();
else setTimeout( function(){ check(done) }, 1000 );
}
before(function( done ){
check( done );
});
it('should get here ONLY once someCondition is true', function(){
// Only gets here once `someCondition` is satisfied
});
})
私が使っているのにあなたが書いたことに驚いています。私はmochaをbddスタイルのテスト(describe/it)で使用し、テストにconsole.logsを追加して、あなたの主張が私のケースに当てはまるかどうかを確認しましたが、そうではないようです。
「end1」と「start1」の順序を確認するために使用したコードフラグメントを次に示します。それらは適切に注文されました。
describe('Characters start a work', function(){
before(function(){
sinon.stub(statusapp, 'create_message');
});
after(function(){
statusapp.create_message.restore();
});
it('creates the events and sends out a message', function(done){
draftwork.start_job(function(err, work){
statusapp.create_message.callCount.should.equal(1);
draftwork.get('events').length.should.equal(
statusapp.module('jobs').Jobs.get(draftwork.get('job_id')).get('nbr_events')
);
console.log('end1');
done();
});
});
it('triggers work:start event', function(done){
console.log('start2');
statusapp.app.bind('work:start', function(work){
work.id.should.equal(draftwork.id);
statusapp.app.off('work:start');
done();
});
もちろん、これも偶然に起こった可能性がありますが、私にはたくさんのテストがあり、それらが並行して実行される場合、私は間違いなく競合状態になります。
Mocha issue trackerの this issue も参照してください。それによると、テストは同期的に実行されます。
mocha-steps を使用します
テストが非同期であるかどうかに関係なく、テストを連続的に実行します(つまり、done
関数はまだ正確に機能します)。これはit
の直接の置き換えであり、代わりにstep
を使用します
私たちのアプリケーションでこれと同じ問題を解決したかったのですが、 受け入れられた答え はうまくいきませんでした。特にsomeCondition
で真になることはありません。
アプリケーションでpromiseを使用します。これにより、テストを適切に構造化することが非常に簡単になりました。ただし、重要な点は、before
フックを使用して実行を遅らせることです。
var assert = require( "assert" );
describe( "Application", function() {
var application = require( __dirname + "/../app.js" );
var bootPromise = application.boot();
describe( "#boot()", function() {
it( "should start without errors", function() {
return bootPromise;
} );
} );
describe( "#shutdown()", function() {
before( function() {
return bootPromise;
} );
it( "should be able to shut down cleanly", function() {
return application.shutdown();
} );
} );
} );