-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
after() not called on error #534
Comments
js examples next time please :p I can verify that it does work fine for me for test-cases, but yes if a hook fails mocha will pretty much bail immediately, though I suppose we could change that behaviour for after / before hooks only |
OK ;) It would be nice as I am using after() for cleanup. In integration tests, database is left in inconsistent state, which may then interfere with next test run. |
well i had this discussion in another issue about trapping signals etc, cleanup in after hooks technically makes little to no sense, but in this case yeah we can definitely get around that |
#516 I guess, yeah ;) |
+1 Yes, It is not very good thing that after hook is not called if suite fails. For example I upload some files to test store to perform there some ops and after tests I want file to be deleted from store. Of course I can design my tests so that it would clean up file store in before hook (and usually i do so), but some times it is more convenient to clean up in after hook. |
+1. Every time my tests fail, I have to change my test data because my cleanup code isn't executed |
I cleanup in |
What if your failure is in the very last test? Then there's not another before hook to execute. I guess you could add an empty test at the end, but that's pretty hacky. |
then it's cleaned up the next time you run the tests. I'm not saying we shouldn't fix this but i think it's bad practice to use after hooks in any test framework for cleanup really because there's no guarantee the framework itself or something else wont cause a fatal error |
In my REST integration tests, the amount of teardown varies significantly by test, and errors will often leave the database in an unknown state. I have a lot of tests, so to add comprehensive teardown coverage using "before" to every test seems like it would add a lot of overhead. Putting the teardown in "after" would allow me to only add the teardown required for that individual test. I would imagine my code will be causing a lot more errors than the framework(s). in that less frequent scenario where the framework causes a fatal error, I can run a cleanup script. Right now I run that script a lot... |
Is this issue being addressed? I have a case where I need to backup some files prior to manipulating them then restore the originals afterwards. It would be really beneficial if I'd even be willing to fix it up myself if someone pointed me to the point in the code which causes it to cease running. |
In some test frameworks there is a 'cleanup' method which can be guaranteed to run before a test, and a 'setup' method which runs before. If the default 'after' behaviour can't be altered to /always/ run regardless of errors, it might be nice to have methods with a similar behaviour to setup/cleanup instead. Trying to ensure a clean state for tests upon each run is quite vital to maintaining a reliable test suite. Another option might be something like after.always(function() { // always run }); |
I can't believe this issue is still not addressed. What is the point of after and afterEach if they don't get called when a test fails? |
I have a test with a forked process, when there is an error, the forked process is not killed because after() never killed it. How would you suggest I kill the forked process? |
we have a lot on our plate folks, we will look into this shortly (within days) |
+1, in my case it's closing a webdriver I'd like to do after a test, independent whether it succeeds or fails. |
I'd also like to see this added. I have the same problem as @samshull—I have a forked process and it won't get cleaned up on an error. I am currently cleaning it up on before(), but this lets the process leak until the tests are re-run. |
@bradjasper I started using
So that I could ensure that it was cleaned up no matter what. |
fixed by #1043 |
I'm having a little trouble following the discussion here - happy to read up if someone can point me in the right direction. Using the after() hook, rather than the before(), helps me prevent tests from clashing with one another when they're being run concurrently (e.g., on Travis).
If the test fails though, I have no way of deleting just those values, which are then stuck in the database until I manually clean them up. Again, sorry if there is already some documentation on this - wasn't able to find it by following the above discussions. |
This is indeed very strange behaviour. Tests do fail and hence the expected behaviour is an order of
|
I don't think this is fixed. My |
post an example of a test suite where it's not working |
I am having an issues where the after does not run if the before hook fails. This is annoying because I do a register and authenticate before and a delete after and the register runs and then authenticate fails and i ahve tons of test data. |
@geoguide, version of mocha and sample test suite where it fails? |
@dasilvacontin 2.1.0
Update! I am using supertest for the assertions. I neglected to mention that originally. |
With mocha 2.1.0 I can't get to reproduce the bug with the following code:
|
Maybe i need to throw the error instead of returning error messages on expects. I thought that was equivalent to throwing an error though. To clarify I'm saying the "it shouldn't execute.." does not execute but the "after" should and does not in my code. |
That's not fixing it. It's very likely I'm formatting the test wrong, because this is my first shot at using mocha. It is basically as you see it, i just tried changing the returns to throw errors and it got more messed up so went back to returning messages. I'll try looking at the docs some more to figure out where I'm going wrong, but for now i just have to make sure those methods in before are working. |
@geoguide, the after hook is executing in my code. Basically you have to throw errors if necessary, either manually, or via a library, like |
Okay, I confirm this is still failing when you are throwing async inside the before. |
Given how long this issue has been around, I suspect this is a relatively recent regression? |
Maybe, our tests for these scenarios suck. |
I'm working on this on PR #1531. |
It seems like I'll have to change the uncaught error listener behaviour, so that I can test a mocha instance using mocha; the main mocha is getting the uncaught errors that are intended to get caught by the mocha instance I'm testing. This might also fix a compatibility error we had with Hapi, or something similar that I read over the repo's issues. |
I recently started using mocha, and I was surprised to see this bug as well. I have some tests that hit a MongoDb database and I wanted to use after to clean up any of the records my tests inserted. I was surprised to find out that "after" did not execute when my tests fail. I look forward to this being fixed. |
I'm getting that problem too, also looking forward for a fix! |
guys! any news here? |
@jifeon should be fixed in the latest release |
Closed via #1802. Thanks @ajaykodali! |
Found a case in which afterEach doesn't run for mocha @ 5.2.0 if the async code is deeply nested and throws an error. Repository here. import { expect } from 'chai';
global.VALUE = 100;
describe('Suite 1', () => {
it('passes a simple test', () => {
expect(true).to.equal(true);
});
it('global value is 0', () => {
expect(VALUE).to.equal(0);
});
})
describe('Suite 2', () => {
const anotherPromiseGuaranteedToFail = async () => {
return new Promise((resolve, reject) => {
// Modifying the global value here..
VALUE = -1;
try {
throw new Error('failure');
} catch (error) {
reject(error);
}
resolve();
});
};
// this before all hook is modifying the global value in an asynchronous way
before(() => (
new Promise((resolve, reject) => {
resolve(0);
}).then(() => {
return anotherPromiseGuaranteedToFail();
})
));
it('passes a simple test', () => {
expect(1).to.equal(1);
});
})
describe('Suite 3', () => {
it('global value is 0', () => {
// fails since afterEach did not set the global value back to 0 after Suite 2
expect(VALUE).to.equal(0);
});
});
afterEach(() => {
global.VALUE = 0;
}); |
The workaround I've found for after:
I didn't check whether it will keep the test stack trace if after raises an error, however it can be wrapped with try/catch as well for sure. |
@igorbunova So, |
Anyway, this bug was fixed a long time ago. You shouldn't experience it unless you're still using |
The text was updated successfully, but these errors were encountered: