Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...

...


Warning
titleOut of date

This information may be out of date. Practices for erm apps specifically have shifted from the stripes standard,  using instead a centralised library sitting between stripes-testing and our modules stripes-erm-testing. The approach to mocking etc has also shifted, and should now be more in line with the jest practices outlined in their documentation.

Table of Contents

This document is a starting/reference guide for writing unit tests for the UI modules within ERM. 

...

Before moving on to an example, queries are an important aspect of testing and choosing the right query within your tests is crucial.

Queries are the methods that RTL gives you to find elements on the page. There are a number of ways in which we can grab an element on a page. 

The following table describes the selectors that you need to use as a priority.

Image Modified

Priority should be give according to the priorities listed here.

...

           To grab a button by the label Save & close, you can either use:

     1) getByRole('button', { name: 'Save & close' })
2) getBylabelText('Save & close')
     Note: You might be tempted to pass data-testid to an element and find an element using the getByTestId query. This attribute is 
provided by RTL only as an escape hatch and should be avoided wherever possible. The attribute is going to eventualy end up
on the dom and we do not want to pollute the dom with avoidable attributes.

...

const onAdd = jest.fn();
const onSubmit = jest.fn();

const basketSelectorProps = {
'addButtonLabel':'add button',
'autoFocus':true,
'basket':[{
'id':'5650325f-52ef-4ac3-a77a-893911ccb666',
'class':'org.olf.kb.Pkg',
'name':'Edward Elgar:Edward Elgar E-Book Archive in Business & Management, Economics and Finance:Nationallizenz',
'suppressFromDiscovery':false,
'label': 'basketSelector'
}]
};

describe('BasketSelector', () => {
test('renders add To Basket button', () => {
const { getByText } = renderWithIntl(
<TestForm onSubmit={onSubmit}>
<BasketSelector {...basketSelectorProps}/>
</TestForm>
);

   expect(getByLabelText(/basketSelector/i)).toBeInTheDocument();
userEvent.click(getByText('add button'));
expect(onAdd.mock.calls.length).toBe(1);
});
});

...

Idealy we would like to have 100% coverage on all the components. Sometimes it feels too trivial to cover certain cases, i.e. the effort in writing the test outweighs the condition you are checking for and that decision is left to the developer.

Using Interactors

One of the advantages of having a custom design system and component library within FOLIO is that we don't start from scratch when writing tests that target an application using it. We know very precisely what the structure the DOM will take, and we can use that knowledge to our advantage when it comes to writing tests, both for manipulating the UI and also for making assertions against it.

Interactors provide us an abstraction between the HTML of our tests, so that not only are tests easy to write, but as the underlying components change and evolve, the tests do not need to change. 

Refer the documentation for interactors to find the list of all the interactors currently available. A good way to understand how tests need to be structured/written using the interactors is to differentiate between the traditional RTL approach and the interactors way. Imagine we are writing a test to assert that a button (rendered via the stripes component Button component) with a specific label is rendered.

...

The EresourceSections have a good set of tests that currently use the MCL, KeyValue, Button and TextField interactors. The documentation for the interactors as pointed above list all the different types of filters, actions and locators that the interactor accepts.

Writing tests for Route level components:

The top level Route components within ERM apps serves as a single component for fetching all the data at the top level required by all its nested children and defining the callback handlers to be passed to the child components. This makes testing these Route level components slightly tricky. The reason being  Route component acts more like a container but not strictly presentation which makes it difficult to write UI tests as there is no DOM to work against and test out the long list of callback handlers each of them contains. Sure, we can let the child components render as is without being mocked but we dont do that as an overall practise within ERM apps and let the tests be as 'unit'y as possible instead of breaking into the integration tests realm.

...

Important note: In the above scenario we are testing if the queryUpdateMock is what gets called, but ideally accordion to RTL philosophy, you test for what changes on the UI when the callback is invoked. If there is an option to test the visual changes on the UI based on the invoked callback, that should be preferred over testing out the implementation details of the callback.

...

Debugging

...

https://testing-library.com/docs/dom-testing-library/api-debugging/

...