Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getting 'test exited without ending' when using subtests with async calls #42

Closed
cappslock opened this issue Jul 24, 2013 · 4 comments
Closed

Comments

@cappslock
Copy link

Found this when writing a test. When using subtests with async calls, test output looks incorrect and test fails with 'test exited without ending'. Here's a simple example:

var test = require('../');

var asyncFunction = function (callback) {
  setTimeout(callback, Math.random * 50);
};

test('master test', function (t) {
  t.test('inner test 1', function (tt) {
    tt.pass('inner test 1 before async call');
    asyncFunction(function () {
      tt.pass('inner test 1 in async callback');
      tt.end();
    })
  });

  t.test('inner test 2', function (ttt) {
    ttt.pass('inner test 2 before async call');
    asyncFunction(function () {
      ttt.pass('inner test 2 in async callback');
      ttt.end();
    })
  });

  t.end(); // test fails with or without this, is t.end in master test necessary?
})

And the output:

TAP version 13
# master test
# inner test 1
ok 1 inner test 1 before async call
ok 2 inner test 1 in async callback
ok 3 inner test 1 before async call
ok 4 inner test 1 in async callback
not ok 5 test exited without ending
  ---
    operator: fail
    expected: 
    actual:   
  ...

Note that the first test is actually run twice. This isn't an issue when removing the async call:

var test = require('../');

test('master test', function (t) {
  t.test('inner test 1', function (tt) {
    tt.pass('inner test 1 no async');
    tt.end();
  });

  t.test('inner test 2', function (ttt) {
    ttt.pass('inner test 2 no async');
    ttt.end()
  });

  t.end(); // test fails with or without this, is t.end in master test necessary?
})

produces:

TAP version 13
# master test
# inner test 1
ok 1 inner test 1 no async
# inner test 2
ok 2 inner test 2 no async

1..2
# tests 2
# pass  2

# ok

I can open a pull request for these tests, if you like.

@AllSpeeds
Copy link

Have you tried simplifying your test:

var test = require('tape').test;

var asyncFunction = function (callback) {
  setTimeout(callback, Math.random * 50);
};

test('master test', function (t) {
  t.pass('inner test 1 before async call');

  asyncFunction(function () {
    t.pass('inner test 1 in async callback');
  });


  t.pass('inner test 2 before async call');

  asyncFunction(function () {
    t.pass('inner test 2 in async callback');

    t.end();
  });
});

This will run all tests and call end when the second async function callback is called. The only problem I can foresee with this solution is in the scenario where the second call to asyncFunction comes back slower than the first since the second contains calls end on the test. You could nest your second test to make sure sure it is run in order:

var test = require('tape').test;

var asyncFunction = function (callback) {
  setTimeout(callback, Math.random * 50);
};

test('master test', function (t) {
  t.pass('inner test 1 before async call');

  asyncFunction(function () {
    t.pass('inner test 1 in async callback');

    t.pass('inner test 2 before async call');

    asyncFunction(function () {
      t.pass('inner test 2 in async callback');

      t.end();
    });

  });

});

Yet another way to write it if you insist on "sub-tests":

var test = require('tape').test;

var asyncFunction = function (callback) {
  setTimeout(callback, Math.random * 50);
};

test('master test', function (t) {
  test('inner test 1', function (tt) {
    tt.pass('inner test 1 before async call');
    asyncFunction(function () {
      tt.pass('inner test 1 in async callback');
      tt.end();
    })
  });

  test('inner test 2', function (ttt) {
    ttt.pass('inner test 2 before async call');
    asyncFunction(function () {
      ttt.pass('inner test 2 in async callback');
      ttt.end();
    })
  });

  t.end(); // test fails with or without this, is t.end in master test necessary?
});

grncdr added a commit to grncdr/tape that referenced this issue Oct 17, 2013
It passes on this branch with no changes, w00t
@grncdr
Copy link
Contributor

grncdr commented Oct 17, 2013

@cappslock please give my PR branch over on #51 a try, I added your test over there and it passed just fine.

@cappslock
Copy link
Author

I'm away from the computer this week but I'll check it out Monday. Thank
you!
On Oct 16, 2013 10:13 PM, "Stephen Sugden" [email protected] wrote:

@cappslock https://github.com/cappslock please give my PR branch over
on #51 #51 a try, I added your
test over there and it passed just fine.


Reply to this email directly or view it on GitHubhttps://github.com//issues/42#issuecomment-26476521
.

ghost pushed a commit that referenced this issue Oct 25, 2013
It passes on this branch with no changes, w00t
@ghost
Copy link

ghost commented Mar 5, 2014

This was added to the test suite and fixed a while back. Closing.

@ghost ghost closed this as completed Mar 5, 2014
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants