22. Testing#
It's good practice to write tests for the requirements of a project. The requirements become clearer. A path towards implementation is emerging.
This chapter is a starting point for testing in Volto.
For information on testing backend code, see the separate training: Testing Plone
Checkout volto-ploneconf
at tag "vocabularies":
git checkout vocabularies
The code at the end of the chapter:
git checkout testing
More info in The code for the training
22.1. Testing the rendering of a component#
With jest
you can create snapshots of components.
Does this snapshot change after a change in the code, you can check if this snapshot change is intentionally caused, and if not, rethink your changes.
Create a
Talk.test.js
file as a sibling ofTalk.jsx
You are testing the component
Talk
. The test is rendering the component with some props:
1import renderer from 'react-test-renderer';
2import { Provider } from 'react-intl-redux';
3import configureStore from 'redux-mock-store';
4import Talk from './Talk';
5const mockStore = configureStore();
6
7const store = mockStore({
8 intl: {
9 locale: 'en',
10 messages: {},
11 },
12});
13
14test('renders a talk view component with only required props', () => {
15 const component = renderer.create(
16 <Provider store={store}>
17 <Talk
18 content={{
19 title: 'Security of Plone',
20 description: 'What makes Plone secure?',
21 type_of_talk: { title: 'Talk', token: 'talk' },
22 details: {
23 'content-type': 'text/html',
24 data: '<p>some details about this <strong>talk</strong>.</p>',
25 encoding: 'utf8',
26 },
27 }}
28 />
29 </Provider>,
30 );
31 const json = component.toJSON();
32 expect(json).toMatchSnapshot();
33});
Create a snapshot by running the tests:
make test
See the snapshot in folder __snapshots__
.
If this is a rendering you expect, you are good to go.
For example you see that the heading is the talk title with preceding type of talk.
packages/volto-ploneconf/src/components/Views/__snapshots__/Talk.test.js.snap
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders a talk view component with only required props 1`] = `
<div
className="ui container"
id="view-wrapper talk-view"
>
<h1
className="documentFirstHeading"
>
<span
className="type_of_talk"
>
Talk
:
</span>
Security of Plone
</h1>
<p
className="documentDescription"
>
What makes Plone secure?
</p>
<div
className="ui right floated segment"
/>
<div
dangerouslySetInnerHTML={
Object {
"__html": "<p>some details about this <strong>talk</strong>.</p>",
}
}
/>
<div
className="ui clearing segment"
>
<div
className="ui dividing header"
>
Speaker
</div>
</div>
</div>
`;
See also
22.2. Testing permissions, features and user interface topics#
With Cypress
you can run browser-based acceptance tests.
The following simple test checks if an editor can add an instance of the custom content type talk
.
The test mimics the editor visiting her site and adding a talk via the appropriate menu action.
Create a test file cypress/tests/content.cy.js
1describe('content type tests', () => {
2 beforeEach(() => {
3 cy.intercept('GET', `/**/*?expand*`).as('content');
4 cy.createUser({
5 username: 'editor',
6 fullname: 'Editor',
7 roles: ['Member', 'Reader', 'Contributor'],
8 });
9 cy.visit('/');
10 cy.wait('@content');
11 });
12
13 afterEach(() => {
14 cy.removeUser('editor', 'password');
15 });
16
17 it('As editor I can add a talk.', function () {
18 cy.autologin('editor', 'password');
19
20 cy.visit('/');
21 cy.wait('@content');
22
23 // when I add a talk with title, type and details
24 cy.get('#toolbar-add').click();
25 cy.get('#toolbar-add-talk').click();
26 // title
27 cy.get('input[name="title"]')
28 .type('Security in Plone')
29 .should('have.value', 'Security in Plone');
30 // type of talk
31 cy.get(
32 '#field-type_of_talk > .react-select__control > .react-select__value-container',
33 )
34 .click()
35 .type('talk{enter}');
36 // details
37 cy.get('.field-wrapper-details .slate-editor').type('This is the text.');
38 cy.get('#toolbar-save').click();
39
40 // Then a new talk should have been created
41 cy.url().should('eq', Cypress.config().baseUrl + '/security-in-plone');
42 // Then the title should read 'Talk: Security in Plone' with the type of talk mentioned
43 cy.get('body').contains('Talk: Security in Plone');
44 });
45});
With a frontend package NOT relying on a backend package, you could proceed with next step Run cypress tests.
Preparing acceptance backend with add-ons#
For a test like above, with talks, the acceptance backend needs the backend package with content type talk to be installed.
Have a look at /frontend/backend/
, where a backend with the add-on ploneconf-site
is configured.
The configuration instructs to install the package from its repository and editable.
So you can proceed developing the backend package while working on the frontend package.
Necessary changes of the backend package while developing the couple of backend add-on and frontend add-on can be committed right out of /frontend/backend/sources/ploneconf.site
.
Run cypress tests#
Go to your frontend folder, start the test backend and the test frontend. Then run the acceptance tests:
It's recommended to start three individual terminal sessions, one each for running the Plone backend, the Volto frontend, and the acceptance tests.
All sessions should start from the frontend
directory.
In the first session, start the backend server.
make backend-install make acceptance-backend-start
In the second session, start the frontend server.
make acceptance-frontend-dev-start
In the third session, start the Cypress tests runner.
make acceptance-test
In the Cypress pop-up test style, choose
E2E Testing
, since Volto's tests are end-to-end tests.In the next section, select the browser you want Cypress to run in. Although the core tests use
headless Electron
by default, you can choose your preferred browser for the tests development.In the main Cypress runner section, you will see all test specs.
To run a test, interact with the file based tree that displays all possible tests to run, and click on the test spec you want to run.
Have a look in the code of volto-ploneconf
to see that the continuous integration includes these cypress tests: .github/workflows/acceptance.yml
.
Commits to pull requests trigger a run of the tests.
See also
Helper functions for an auto login, creating content, etc. from Volto.