Illustration de l'article

How to test your DOM by being resilient to design changes ?

Écrit par alban@sogilis.com

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

Alban Bertolini

Special thanks to Jean-Baptiste, Yann, Nasser and Julio for their feedbacks.

Illustration de l'article
comments powered by Disqus