DEV Community

Cover image for The importance of testability for web testing automation
Walmyr
Walmyr

Posted on • Edited on

The importance of testability for web testing automation

Learn how to improve the readability of automated tests written with the Cypress framework

Does your team care about testability?

If so, this post is for you!

One way to check the testability of a web application is to inspect the frontend elements and verify if they have attributes added specifically to facilitate the automation of graphical interface tests, such as data-test, data-test-id, data-qa, data-cy, etc.

Imagine the following HTML form.

<!-- ./index.html -->

<form name="login-form">
  <label for="email">Email</label>
  <input type="email" name="email" id="email" data-test="email-field" required />
  <label for="password">Password</label>
  <input type="password" name="password" id="password" data-test="password-field" required />
  <button type="submit" data-test="login-button">Login</button>
</form>
Enter fullscreen mode Exit fullscreen mode

As you can see, all the elements we need to automate such a form have data-test attributes.

This is an example of testability.

And why is this important?

When the frontend of a web application has attributes specifically created for testability purposes, there is less risk that changes to its logic or style will break the tests.

Now, let's look at a test (written with Cypress) that fills out such a form.

// cypress/integration/loginForm.spec.js

beforeEach(() => {
  cy.visit('./index.html')
})

it('successfully logs in', () => {
  const email = Cypress.env('userEmail')
  const password = Cypress.env('userPassword')

  cy.get('[data-test="email-field"]').type(email)
  cy.get('[data-test="password-field"]').type(password, { log: false })
  cy.get('[data-test="login-button"]').click()

  cy.contains('You\'re now logged in!').should('be.visible')
})
Enter fullscreen mode Exit fullscreen mode

The test above makes use of such attributes, however, there is some repetition in the selection of elements, where the only part that changes are the values of the data-test attribute.

What if we could improve this?

Well, we can!

See the new version of the test below.

// cypress/integration/loginForm.spec.js

beforeEach(() => {
  cy.visit('./index.html')
})

it('successfully logs in', () => {
  const email = Cypress.env('userEmail')
  const password = Cypress.env('userPassword')

  cy.dataTest('email-field').type(email)
  cy.dataTest('password-field').type(password, { log: false })
  cy.dataTest('login-button').click()

  cy.contains('You\'re now logged in!').should('be.visible')
})

Cypress.Commands.add('dataTest', value => {
  return cy.get(`[data-test="${value}"]`)
})
Enter fullscreen mode Exit fullscreen mode

Now, instead of all that repetition, we have a custom command that abstracts this logic, and the test itself is clean, passing to the .dataTest command the appropriate value depending on the element we want to select.

Note: Ideally, such custom command would be defined in the cypress/support/commands.js file, however, in this case I left it directly in the test file for teaching purposes.

See the test running.

Image description

That's it!


Did you like the content? Leave a comment.

Also, access the complete code on GitHub.


Curious and want to learn more about Cypress Testing Automation? Check out my courses on Udemy.


👋 Until next time and happy testing!


This post was originally published in Portuguese at the Talking About Testing blog.

Top comments (0)