-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
add option to fail tests that print errors and warnings #6121
Comments
This can already be achieved with a couple lines of code. const spy = jest.spyOn(global.console, 'error')
// ...
expect(spy).not.toHaveBeenCalled(); |
@apaatsio is correct - the way to do it is something like that example |
@apaatsio how would you suggest someone implement this so that it runs across all test suites without having to include it in each individual test suite? |
|
To get it working I've ended up with this ugly thing
requirements:
|
Note: I've tried lots of simpler ideas and they all fell down somehow. |
Is there a preferred way to do this globally that doesn't involve adding a I'm looking at the solution from here, which seems to do the job:
|
@stevula For what it's worth, that's exactly what works for me |
Yup, that's the preferred way to do that globally |
Thanks, @stevula – that's close, but the problem is that the
You can see the interpolated message too, but it's a little cumbersome. :) |
@akx as an option you can iterate through all the arguments and replace all possible substitutions strings with values, i.e.
|
When I tried this option I got an error on executing because of Create React App: So I wrote a bash script to for manually looking for consoles and warnings (it can be found here). Later I discovered that options not supported by React Create App on jest configurations can be used via the command line. So one could run: npm test -- --setupFiles './tests/jest.overrides.js' instead of changing package.json, and the solution pointed by @stevula would work. |
@icaropires If you want to disallow |
@scotthovestadt Thanks for the suggestion. I did put it as a lint rule for my team's code. But in case of warnings, consoles were being called from inside my libraries: This picture from my CI shows that. |
@lukeapage Thank you for contributing that solution (#6121 (comment)) -- just a note about it: You're going to get May I suggest either using console.log in their place if you want the whole stack trace, or just letting jest spit out the original error/warning to stdout, and throwing the error as usual? See below for revised code:
|
@sdushay it does not recourse because once you grab a reference locally it is immune to spying. That’s why it’s calling original. The code above or a slight variation on it runs and works for us. |
@lukeapage You're right, I don't know what was blowing our call stack. |
….warn() is used For example Vue complains when a directive can not be found using console.warn() but continue the execution. In this situation the test should be marked as failed because there is something not expected going on. The solution is extracted from [0]. [0] jestjs/jest#6121 Part of request #13806: Use Jest as the default test framework for JS unit tests Change-Id: I3e88eb41c9a1acbe0e7698f6a53f08453e7f5950
Here's the variant I landed on, using Node's // setupTests.js
import { format } from "util";
const error = global.console.error;
global.console.error = function(...args) {
error(...args);
throw new Error(format(...args));
}; cc @akx, re:
|
@greypants' version does not work for me with async tests. I'm trying to detect errors logged by React Testing Library - e.g. when a render is triggered after a test has completed. Throwing in The version below, adapted from @sdushay, works nicely. It fails any async test that logs an error or warning to the console without affecting the others. Note that it is also compatible with ESLint's let consoleHasErrorOrWarning = false;
const { error, warn } = console;
global.console.error = (...args) => {
consoleHasErrorOrWarning = true;
error(...args);
};
global.console.warn = (...args) => {
consoleHasErrorOrWarning = true;
warn(...args);
};
afterEach(() => {
if (consoleHasErrorOrWarning) {
consoleHasErrorOrWarning = false;
throw new Error('Console has error or warning');
}
}); |
We also needed this and having a working version both for sync and async tests was not trivial. Especially if you don't want to lose the stacktrace, have a nice output and not have weird behaviors. We ended up using some code from React's repository and I made it compatible with plain Jest : https://github.com/ricardo-ch/jest-fail-on-console |
I have also stumbled uppon the maximum callstack problem referenced when using the #6121 (comment) solution. But to be honest I didn't understand the point of calling
This was the result prior to overriding console warns: And this is the result with above code: The initial point was to fail a test if it throws internally console.warns or console.errors. And this works for me. I haven't tried the async part yet (as mentioned in #6121 (comment)), but for now it works just fine and also it preserved the original stack trace. |
Building up on @axelboc's variant: // check if console was used
let usedConsole = false;
['log', 'error', 'warn'].forEach((key) => {
const originalFn = console[key];
console[key] = (...args) => {
usedConsole = true;
originalFn(...args);
};
});
// check if a test failed
// see https://stackoverflow.com/a/62557472/1337972
jasmine.getEnv().addReporter({
specStarted: (result) => (jasmine.currentTest = result),
});
afterEach(() => {
// if test hasn't failed yet, but console was used, we let it fail
if (usedConsole && !jasmine.currentTest.failedExpectations.length) {
usedConsole = false;
throw `To keep the unit test output readable you should remove all usages of \`console\`.
They mostly refer to fixable errors, warnings and deprecations or forgotten debugging statements.
If your test _relies_ on \`console\` you should mock it:
\`\`\`
const errorSpy = jest.spyOn(console, 'error');
errorSpy.mockImplementation(() => {});
errorSpy.mockRestore();
\`\`\`
`;
}
}); |
If you are using We are using In jest config: in
|
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Do you want to request a feature or report a bug?
Feature.
What is the current behavior?
Tests pass even if they print errors and warnings to the console.
What is the expected behavior?
It would be nice if we could force the test to fail.
Our test suite prints lots of things like this:
These are all legitimate errors that we should fix, yet our automated tests pass. If Jest could be made to fail, that would encourage developers to keep the tests clean.
The text was updated successfully, but these errors were encountered: