-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Fail tests that finish with pending assertions #1335
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
Fail tests that finish with pending assertions #1335
Conversation
`t.throws()` and `t.notThrows()` can be called with an observable or promise. This commit forces users to wait for the assertion to complete before finishing the test. Usually this means the test has to be written like: ```js test(async t => { await t.throws(Promise.reject(new Error())) }) ``` Or for callback tests: ```js test.cb(t => { t.throws(Promise.reject(new Error())).then(t.end) }) ``` This simplifies internal logic and helps discourage code like in #1327. Anecdotally users are surprised by the previous behavior where a synchronous test worked with an asynchronous assertion (#1327 (comment)). Fixes #1327.
Can we detect Promise/Observable being passed to |
No, since we don't know a test is synchronous until the function returns. |
But can't we throw when the test returns then? We could have |
This is actually already caught by another check (nice!), but would be useful to have a better message for it. import test from 'ava';
const foo = () => Promise.resolve('foo');
test(t => {
t.throws(foo());
});
|
Yay. I'm very happy about this change. |
Right. |
@novemberborn We could if it's not too hard. I would also be good with just failing the test saying something like:
That's at least clearer than:
|
It's not too hard.
Unfortunately even if a test is asynchronous, that doesn't mean it's waiting for the assertion to complete. |
This change broke our test helpers - we were using t.notThrows to declare mocked functions that must be called. Now, instead of getting a specific error message, we get a generic "Test finished, but an assertion is still pending" instead of the error message passed into t.notThrows(promise, ), or the rejection itself. |
@joflashstudios for a generic solution you could |
@novemberborn The problem is that the t.notThrows() calls need to be non-blocking, because they happen before the promise gets resolved. |
You could keep a reference to the returned promises, and then at the end of the test implementation do test('something', interceptNotThrows(t => {
t.notThrows(somethingAsync())
})) |
t.throws()
andt.notThrows()
can be called with an observable or promise. This commit forces users to wait for the assertion to complete before finishing the test. Usually this means the test has to be written like:Or for callback tests:
This simplifies internal logic and helps discourage code like in #1327. Anecdotally users are surprised by the previous behavior where a synchronous test worked with an asynchronous assertion (#1327 (comment)).
Fixes #1327.