The importance of testability for web testing automation
Tags: cypress, testing, webtesting, testability
Published: 2022-01-07 16:39:22

## 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.

```html
<!-- ./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>
```

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**](https://cypress.io)) that fills out such a form.

```js
// 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')
})
```

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.

```js
// 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}"]`)
})
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66olj8cd7p53leytae0z.gif)

That's it!

___

Did you like the content? Leave a comment.

Also, access the [**complete code on GitHub**](https://github.com/wlsf82/cy-data-test).

___

Curious and want to learn more about **Cypress Testing Automation**? Check out my courses on [**Udemy**](https://udemy.com/user/walmyr).

___

👋 Until next time and happy testing!

___

This post was originally published in Portuguese at the [**Talking About Testing**](https://talkingabouttesting.com/2022/01/06/a-importancia-da-testabilidade-para-testes-automatizados-web/) blog.