Debugging unit tests
If you encounter any issues with unit tests, this page contains techniques you can use to help you troubleshoot.
Use logging
To run tests with some extra debugging info, you can pass a
--log-level
:
yarn test:unit --log-level debug
You can put a
console.log()
in your test code. When you run the test, the output will be in the command line.
Use Chrome devtools to debug unit tests
Go to chrome://inspect/.
Add a
debugger
statement in your test code and if you want to run only your test add the .only on your test like so. Make sure to remove the .only once you are done.CODEit.only('testing something', () => { debugger expect(value).to.eq(true); })
Run in the terminal
CODE$ BABEL_ENV=test node_modules/.bin/mocha --inspect-brk --config config/mocha.json --recursive '{test,src}/**/*.unit.spec.js?(x)' src/platform/testing/unit/helper.js
Go to your Node Chrome Developer Tools. Under
Remote Target
you should see your test running. Click on the link where your test is running to open the debugger tool.You will want to press the debugger play button to start the program. It will initially pause on the first line of code.
It might take awhile for the tests to setup, just be patient and eventually it will run.
Once the test runs, your code should break at your debugger statement.
Use VSCode's debugging tool for unit tests
Add this
Mocha Tests
configuration to your.vscode/launch.json
fileCODE{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Mocha Tests", "env": {"BABEL_ENV": "test"}, "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/mocha", "runtimeArgs": [ "--inspect", "--config", "${workspaceFolder}/config/mocha.json", "--recursive", "${workspaceFolder}/{test,src}/**/*.unit.spec.js?(x)", "${workspaceFolder}/src/platform/testing/unit/helper.js" ], "port": 9229 } ] }
Now you can add breakpoints or debugger statements to debug your code through the VSCode debugger tools.
How to debug (and avoid writing!) flaky unit tests
Background
The most important thing to understand about the writing tests for VA.gov applications is that Mocha does not run individual tests in isolation. This means that any test you write can affect any other test, and any other test can affect your test.
How to avoid writing flaky unit tests
Global variables
Be sure that you restore any modified globals (such as navigator
) to their original state in an after
or afterEach
hook.
Node.js require caching
If you require()
a file in one unit test and modify the required object, those modifications will be preserved in other unit tests, even when you require the same file again! Ways to avoid this problem:
Don't
require()
the same file twice (e.g. use separate fixture files)Invalidate the require cache once your test is complete.
How to debug flaky unit tests
Unit tests are run in a different order each time tests are run locally or in CI. To re-run tests in the same order, use the same CHOMA_SEED
value. You will see output in the CI logs similar to the following:
choma: to re-use this ordering, run tests with CHOMA_SEED=JAM0CXhqeC
You can then re-run tests in the same order with:
CHOMA_SEED=JAM0CXhqeC yarn test:unit --log-level=error
Note that it's important to run the entire test suite to catch issues caused by tests from other applications. If the issue is test order dependent, you should see the same failure. To speed testing cycles, you may also include the paths to specific unit test files to avoid having to run the entire test suite once you've determined which files are in conflict.
waitFor
When testing components that update in response to asynchronous behavior (e.g. - responding to events, fetching and updating state) you may encounter a scenario where your tests pass in isolation, yet fail in when grouped with the larger test suite. Consider the following React component that calls a redirect
function if the user is signed in, state is not loading, and the feature toggle is not enabled.
A unit test scenario for this component in vets-website
might look like the following:
Running this test works fine when run in isolation, or when grouped with other unit tests within a vets-website
application. However, because of the asynchronous nature of useEffect
, problems will arise when running many tests in parallel.
The solution here is to waitFor
the asynchronous call to redirect
by useEffect
.
If you find yourself scratching your head as to why your unit tests run "just fine" locally, yet fail as part of the larger test suite, ask yourself, "Is my expectation dependent on the execution of asynchronous code, such as fetching data, a promise resolving, or calls to useEffect
?" If so, try wrapping your expectation with waitFor
, push your changes, and let CI tell you if your test flakiness has been resolved.
Help and feedback
Get help from the Platform Support Team in Slack.
Submit a feature idea to the Platform.