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>
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')
})
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}"]`)
})
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.
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)