Skip to main content
Skip table of contents

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:

CODE
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

  1. Go to chrome://inspect/.

  2. 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.

    CODE
      it.only('testing something', () => {
        debugger
    
        expect(value).to.eq(true);
      })
    
  3. 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
    
  4. 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.

  5. You will want to press the debugger play button to start the program. It will initially pause on the first line of code.

  6. It might take awhile for the tests to setup, just be patient and eventually it will run.

  7. Once the test runs, your code should break at your debugger statement.

Use VSCode's debugging tool for unit tests

  1. Add this Mocha Tests configuration to your .vscode/launch.json file

    CODE
      {
        "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
            }
        ]
      }
  2. 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:

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:

CODE
choma: to re-use this ordering, run tests with CHOMA_SEED=JAM0CXhqeC

You can then re-run tests in the same order with:

CODE
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.


JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.