How to test your DOM by being resilient to design changes ?
For the article the technical stack used is Vue.js front-end framework and Jest testing framework
Let’s introduce the problem by an example
We have a button to go to the previous page.
<div class="btn-arrow" @click="goToPreviousPage">
Back
</div>
And the unit test:
it('goes to the previous page when back button is clicked', () => {
// mock goToPreviousPage method
wrapper.vm.goToPreviousPage = jest.fn()
wrapper.find('.btn-arrow').trigger('click')
expect(wrapper.vm.goToPreviousPage).toHaveBeenCalled()
})
Now we want to change the design by replacing .btn-arrow
to .btn-link
css class.
The design can also change by adding tag like div
, a
, span
etc..
<div class="btn-link" @click="goToPreviousPage">
Back
</div>
But now, our test is red because the css selector is undefined
while the functionality still works.
Solution
The solution to be resilient to this kind of changes is to introduce HTML data-*
attributes in your DOM.
Let’s take the World Wide Web Consortium (W3C) definition:
Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.
We can add to our HTML a data-test
attribute to test our DOM.
<div class="btn-link" data-test-action="previous-page" @click="goToPreviousPage">
Back
</div>
it('goes to the previous page when back button is clicked', () => {
// mock goToPreviousPage method
wrapper.vm.goToPreviousPage = jest.fn()
wrapper.find('[data-test-action="previous-page"]').trigger(‘click’)
expect(wrapper.vm.goToPreviousPage).toHaveBeenCalled()
})
Now our unit test has become resilient to design changes because we used data attribute as css selector.
This tip has some drawbacks
- Bigger HTML, degraded readability.
- Take time to add data attributes.
See also
- W3C official definition: https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#custom-data-attribute
- MDN explanations: https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
- W3Schools summary: https://www.w3schools.com/tags/att_data-.asp
Alban Bertolini
Special thanks to Jean-Baptiste, Yann, Nasser and Julio for their feedbacks.