-
Notifications
You must be signed in to change notification settings - Fork 628
Unit & Integration tests
We run mainly two types of tests
- Unit/Integration tests
- Testing Library (React)
- E2E tests
- Cypress
Require NodeJs 14.x or higher, and npm 6.0 or higher.You may use nvm
for installing/managing Node and NPM tools.
Before running either unit tests or integration test, Go to the application root directory where package.json
file is located
i:e:
<apim-apps-root>/portals/publisher/
and run
npm ci
command to download all the dependencies.
To run the unit tests, simply execute the npm test
command in the application root directory (where the package.json file located).
npm test
is an alias to jest
command defined in package.json
.
Test files are located in <Product-APIM-Root>/modules/integration/tests-integration/tests-backend/src/test/resources/jest-integration-tests/
).
Go to the above location and run
npm test
for more information read the integration test README.md file
Run the command
npm run test:coverage
to generate the code coverage for unit tests.Once generated, The coverage reports will be available in <APP_ROOT>/coverage/
directory.
We use Jest framework for managing the unit tests.it also been used as the assertion library as well. For DOM testing, out of the available libraries such as react-testing-library
, Enzyme
, and React's TestUtils
, etc. . . we have mainly used Enzyme
.
Test files naming convention is to add test of a component in the same name as the component's file name in the same location. For example if you write a new component name MySampleComponent.jsx
then use MySampleComponent.test.jsx
as the test file name for that component.
Jest will pickup the files for test which are ending with .test.jsx
or .test.js
Feel free to update this guide , If you able to find better alternatives or if you find anything that is worth adding here
ResolverError: Error downloading https://raw.githubusercontent.com
This could be due to getting throttled out in github public requests, Wait for few seconds(max 1min) and re-run the tests
ResolverError: Error downloading https://raw.githubusercontent.com/wso2/carbon-apimgt/master/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml
at node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/http.js:127:16
Try following command and increase the watch counts
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
NOTE
Below FAQ's are related to older Enzyme based tests, Just keeping theme here as an archived item, Do not encourage to add or modify any answers below
This could happen due to failures in mounting child component, Or your test might take longer time to re-render after a state change. In this case , We could do the suggested workaround in here Or this workaround
In this case, You might probably looking at wrong component instance (element), Use wrapper.debug()
to find out which component is wrapped in
You probably missed some wrapper.update()
calls there. This is an asynchronous call, So make sure to use await
.
For more info refer this issue
If you expect a component to be there in the rendered output but it's not there, That means you probably have check for the component before all the asynchronous calls get succeed (or get executed).
This could mostly happen if you have mocked an API response with a Promise.resolve()
and haven't use await
on the dom update or haven't flush the pending Promise resolves.
So in this case either you have to use
await new Promise(resolve => setImmediate(resolve));
To wait for all the promises to get resolve (Exhausts all promises queued) ( source: this comment)
Or you need to use await
for all the wrapper modification. i:e Event simulations etc.
This is exception is thrown if you haven't mocked the REST API calls. So use Jest.fn()
or Jest.mock('path/to/module')
to mock the relevant API calls.
Most of the components int he Publisher app are decorated by one or more higher order components provided by various libraries, i:e most of the components are wrapped with withStyle
higher order components to get the theming support from Material-UI, Similarly we have user withRoute
to get routing details from react-router and injectIntl
to get internationalization (i18n) support to the components.
for example in Listing.jsx
we have used both injectIntl
and withStyles
higher order functions
export default injectIntl(withStyles(styles)(Listing));
In this case, Enzyme shallow rendering will just render the outer most component , which is intl wrapper and will not actually render the intended Listing component, So we need to unwrap the HOC, before shallow rendering the component.
When doing Enzyme mount, These HOCs would require some values to be there in the context. Do the following as required
-
For React Intl wrapper
Use the IntlHelper.js If we could not survive with this Util we might need to add this package to get the full support i:e
import { mountWithIntl } from 'AppTests/Utils/IntlHelper'; . . . let wrapper = await mountWithIntl(ThemedListing);
-
React router
Use MemoryRouter
for wrapping the component, for example in Listing.test.jsx
<MuiThemeProvider theme={createMuiTheme(light)}>
<MemoryRouter>
<Listing />
</MemoryRouter>
</MuiThemeProvider>
-
Material-UI testing
- If you's test involves inserting, reading , modifying a value in material-ui component, checkout their test implementation for that component in materia-ui git repo. You will be able to get an idea of how to implement testing for your use case using material-ui components
Use unwrap
util from material ui test utils to unwrap the withStyle
decorations,
import { unwrap } from '@material-ui/core/test-utils';
const UnwrappedMenuButton = unwrap(MenuButton);
When enzyme mounting use actual theme object and MuiThemeProvider
component to wrap the target component.Like in the above (intl) example
If you want to change the mocked function behavior between different test cases within one test description(file), Use mockReset
, mockRestore
or mockClear
accordingly. FOr more info refer this issue