This post provides comprehensive guidelines and best practices for web automation testing using tools like Jest and React Testing Library. It covers essential tips for writing effective tests, debugging techniques, and common pitfalls to avoid. Additionally, it includes practical examples and commands to help developers implement robust testing strategies in their projects.
Make your test FAIL AT BEGINNING. Otherwise it may not work properly as you thought.
(For UI Test) Test the feature like a user instead of a developer. We don't need to test the implementation details.
Only write test for current layer, do not drill down, we can create another test case to cover deeper layers/components
Do not include more dependencies if you can do it with Vanilla JS + Jest + Mock
All unit tests should be able to run WITHOUT NETWORK. Disable your network and run it to make sure no request sent.
You can print log in HTTP module to check if any request are sent
Run unit tests in PR pipeline and run integration tests (+E2E tests) on deploy pipeline.
Modularization: Input and output should be clear for a module, which could be more testing-friendly
Try to use hardcoded string on testing, if the constant variables changed, the test case will find the change and notify you
Try to write new feature together with test case (or follow the TDD pattern from start of your project)
Best Practice
Commands
Purpose
Command
Comment
Run single test file
npx jest src\folder\yourComponent1.test.js
Find the file first
Run single test case by case name (Recommended)
npx jest -t='keyword' --watch
Provide a keyword and run test with keyword
Debug
screen.debug():
Prints the HTML to CLI, usually it will only print part of the content, you can set the env var to show more: DEBUG_PRINT_LIMIT=20000. Or you can set the env var in test cases: process.env.DEBUG_PRINT_LIMIT = 20000;
screen.logTestingPlaygroundURL():
Generate an URL powered by testing playground, you can open the url within browser.
Note that theme provider may not work
it.only/describe.only to run only single test case/suite
/* import all */import * asRequestUtilsfrom'src/utils';
/* DO NOT DO THIS */// import RequestUtils from 'src/utils';
jest.spyOn(RequestUtils, 'requestUtil').mockImplementationOnce(() => {
returnPromise.reject('mocked error');
})
const { container } = renderer(
<MyComponent />
);
expect(container).not.toBeNull(); /* This works */
const { container, getByRole } = renderWithState( /* renderWithState may render 'MyComponent' with Providers */<MyComponent />
);
/* Potentially this will be always true because we have wrap 'MyComponent' with Providers */expect(container).not.toBeNull();
/* Try to do other assertions on the elements within container instead of just check container */
Jest Hints
jest.mock() hoists mocks to the top of your module’s scope
TypeError: Expected container to be an Element, a Document or a DocumentFragment but got string
import {
fireEvent,
queryByRole, /* DO NOT DO THIS */
render,
waitFor
} from'@testing-library/react';
const {
container, queryByRole /* DO THIS */
} = render(<App />);
data-testid shows in React Dev Tools but not in Element Tab
Prevent to put the data-testid to custom components.
Otherwise we need to pass the data-testid to children components explicitly.
ß