DevExtreme React - Components Testing
To test DevExtreme UI components for React, add the React Testing Library library to your project.
This library is automatically added when you create a React project with the Create React App. Alternatively, you can use the following npm command to add the React testing library:
npm install --save-dev @testing-library/react
Unit Testing
Unit testing allows you to test single features (units of the code). A unit can be a function or class.
The example below illustrates how to create a unit test for the DataGrid UI component.
Create a simple React application and add DevExtereme to it.
npx -p devextreme-cli devextreme add devextreme-react
Add the following imports to the project. Note that this code also loads jQuery, QUnit, and DevExtreme libraries from CDN.
<!--App.js--> // Import dependencies import React from 'react' import {render, screen, waitFor} from '@testing-library/react' import '@testing-library/jest-dom' // Import a component import DataGridComponent from './DataGrid'
Add the following script to test the DataGrid configuration and the number of loaded records:
<!--App.js--> import React from 'react'; import DataGrid from 'devextreme-react/data-grid'; const dataSource = [{ id: 1, text: 'test' }, { id: 2, text: 'test' }, { id: 3, text: 'test' }, { id: 4, text: 'test' }] export default function DataGridComponent() { return ( <DataGrid dataSource={dataSource} /> ); } test('renders DataGrid', async () => { render(<DataGridComponent />); await waitFor(() => { const rowElements = screen.getAllByText('test', {exact: false}); expect(rowElements.length).toBe(4); }) });
In a project, use the npm test
command to run the test and see the result.
Integration Testing
Integration testing helps test a component across multiple units. Integration testing does not test unit by unit, but tests all the units as an entity.
The example below illustrates how to test the DataGrid's functionality. The test code adds a new row, saves it, and checks the results.
To get started, create a React application as described in the Unit Testing article and add the test code. This code creates the DataGrid and calls the addRow and saveEditData methods to create a new row. Timers allow you to call methods continually since all the processes are asynchronous. The final step is to check whether the DataGrid has two visible rows — an initial row and a newly created row.
import React from 'react'; import DataGrid, { Editing } from 'devextreme-react/data-grid'; const dataSource = {key: 'id', store: [ { id: 1, text: 'test' }, { id: 2, text: 'test' }, { id: 3, text: 'test' }, { id: 4, text: 'test' } ]}; export default function DataGridComponent(props) { return ( <DataGrid ref={props.setRef} dataSource={dataSource} > <Editing mode={'batch'} /> </DataGrid> ); } test('renders DataGrid', async() => { const dataGridRef = React.createRef(); render(<DataGridComponent setRef={dataGridRef} />); //DataGrid is rendered asynchronously, so we need to use async/await and waitFor await waitFor(() => { const rowElements = screen.getAllByText('test', {exact: false}); }) dataGridRef.current.instance().addRow(); //give time to render jest.advanceTimersByTime(200); dataGridRef.current.instance().saveEditData(); //give time to render jest.advanceTimersByTime(200); expect(dataGridRef.current.instance().getVisibleRows().length).toBe(5); // eslint-disable-next-line testing-library/no-wait-for-multiple-assertions expect(dataGridRef.current.instance().hasEditData()).toBe(false); });
Run npm test
command in a test project to see the detailed report of the test and its result.
End-to-End Testing
End-to-End (Functional) testing ignores the component's internal structure and allows you to verify how DevExtreme components work from a user's point of view.
The example below illustrates how to create an End-to-End test for the DataGrid's functionality. The test code emulates a click on the pager.
Сreate a React application as described in the Unit Testing article and add the test code. This code finds the specified link on the pager and clicks it. A click on the pager triggers the click
event. The test checks whether the result page index is the same as the expected page index.
import React from 'react'; import DataGrid, { Editing } from 'devextreme-react/data-grid'; const dataSource = {key: 'id', store: [ { id: 1, text: 'test' }, { id: 2, text: 'test' }, { id: 3, text: 'test' }, { id: 4, text: 'test' } ]}; export default function DataGridComponent(props) { return ( <DataGrid ref={props.setRef} dataSource={dataSource} > <Editing mode={'batch'} /> <Paging pageSize={3} /> </DataGrid> ); } test('Page index is changed from dxPager', async() => { const dataGridRef = React.createRef(); const { container } = render(<DataGridComponent setRef={dataGridRef} />); //DataGrid is rendered asynchronously, so we need to use async/await and waitFor await waitFor(() => { const rowElements = screen.getAllByText(/test/i); }) // eslint-disable-next-line testing-library/no-container,testing-library/no-node-access fireEvent.click(container.querySelectorAll('.dx-page')[1]); //give time to render jest.advanceTimersByTime(200); expect(dataGridRef.current.instance().pageIndex()).toBe(1); });
If you have technical questions, please create a support ticket in the DevExpress Support Center.