Unit tests
Last Updated:
All new code that is added to vets-website
should be unit tested and unit tests should cover at least 80% of code paths. Write unit tests as you build to make sure your form (or other component) is behaving as you expect and to help guard against future bugs. For example, you might create a unit test file for each page in a form and then test the following scenarios:
The correct number of inputs show up when you render the page.
The correct number of fields display validation errors if you submit without entering any information.
Any conditional logic on the page displays under the correct conditions.
For more detailed information about unit test best practices and an in-depth discussion of how they apply to vets-website
, please view this recording of Front End Unit Tests on VA.gov - Best Practices/Q&A Brown Bag Training.
Overview
Unit test file format: file_name.unit.spec.js
Where: Any file_name.unit.spec.js file located in the /src
folder. This file is usually located in a test directory close to the code being tested.
When: Run the test locally through npm script commands, during the Github Actions build (Unit), and after merging to main.
The vets-website
repo uses:
Mocha for running unit tests
Chai for test assertions
React Testing Library (RTL) and Enzyme for mounting and inspecting React components
We encourage the use of RTL in place of Enzyme. (See the migration docs)
Sinon for stubs and spies
Unit tests are collocated with the application folder in a test directory that matches the application directory structure:
- 📂 src
- 📂 my-application
- 📂 components
- MyComponent.jsx
- 📂 tests
- 📂 components
- MyComponent.unit.spec.jsx
Mocha runs any file_name.unit.spec.js file located in the /src
folder. This file is usually located in a test directory close to the code being tested.
Unit test conventions
Use
describe
to organize tests by application and feature. Two levels should be adequate depending on the size of the application being tested. Try to avoid nesting deeper than two levels.Use
it
to describe the unit test:Use active voice.
Describe the behavior in terms specific to the unit.
Do not abstract the test description with business logic.
Recommended:
it('truncates the address property when it is longer than 15 characters')
it('renders an error when props.errors contains at least one item')
Not recommended:
it('shortens the address when the user has a long address')
it('shows an error when the user is not logged in')
Testing components
Use React Testing Library's render
function when testing components.
import React from 'react';
import { render } from '@testing-library/react';
import MyComponent from '../../components/MyComponent';
describe('MyComponent', () => {
it('renders', () => {
...
render(<MyComponent />);
...
});
});
If you're using Enzyme, use shallow instead of mount when possible to test components. Always unmount
components at the end of the test.
import React from 'react';
import { mount } from 'enzyme';
import MyComponent from '../../components/MyComponent';
describe('MyComponent', () => {
it('renders', () => {
...
const form = mount(<MyComponent />);
...
form.unmount();
});
});
Other utilities
These utilities can be found in platform/testing/unit/helpers.js
:
mockFetch()
- A function to mock the global fetch function and return the value provided in returnValresetFetch()
- Resets the mocked fetch set withmockFetch()
mockApiRequest()
- DecoratedmockFetch()
that adds typical API headers toreturnVal
mockMultipleApiRequests()
- DecoratedmockFetch()
that mocks a fetch call for each response object in an array
mockFetch(
new Error('fake error'), // returnVal
false, // shouldResolve: false returns rejected promise. default is true
);
Note: This utility can be found in platform/utilities/storage/localstorage.js
.
getLocalStorage()
- convenience accessor for local storage and implements a fallback. Useful for stubbinglocalstorage
.
Examples and guides
Libraries
mocha.js: Test framework.
chai.js: BDD/TDD assertion library.
chai-as-promised: Extends Chai with assertions about promises.
sinon.js: Standalone test spies, stubs, and mocks.
React Testing Library: React Testing Library is a branch of
Testing Library
that allows users to test their React components through actual DOM nodes instead of rendered instances.Enzyme: Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output. You can also manipulate, traverse, and in some ways simulate runtime given the output.
enzyme-adapter-react-16: Enzyme React 16 integration.
react-dom: React DOM library needed for testing React components.
react-dom/test-utils: Test utilities for React DOM.
react-test-renderer: This package provides an experimental React renderer that can be used to render React components to pure JavaScript objects, without depending on the DOM or a native mobile environment.
jsdom: A JavaScript implementation of WHATWG DOM and HTML standards, for use with node.js.
choma: Random execution order for mocha suites.
Help and feedback
Get help from the Platform Support Team in Slack.
Submit a feature idea to the Platform.