Hoje em “pitadas de Cypress”, aprenda como criar código reutilizável
Muita gente vem me pedindo para falar sobre “Page Objects ou App Actions?”
Aos que querem entender melhor sobre o assunto, além da fonte oficial (blog do Cypress.io), recomendo a live #15 do canal TAT.
Neste post não vou me ater em Page Objects versus App Actions. O foco aqui será em Comandos Customizados, onde alguns deles podem ser considerados App Actions. A comparação entre Page Objects e App Actions vai ficar para outra publicação.
Para explicar, vou usar como exemplo o repositório do projeto wlsf82/gitlab-cypress.
Neste projeto, resolvi separar os comandos customizados entre comandos que ocorrem à nível de API (os quais podem ser considerados App Actions), e os que ocorrem via GUI (os quais são só comandos customizados).
Ou seja, dentro do diretório cypress/support/ tenho a seguinte estrutura de arquivos.
cypress/support/ api_commands.js gui_commands.js e2e.js
SIM, VOCÊ PODE TER QUANTOS ARQUIVOS DE COMANDOS CUSTOMIZADOS VOCÊ QUISER!
E a partir do arquivo cypress/support/e2e.js, importo ambos arquivos api_commands.js e gui_commands.js.
import './api_commands' import './gui_commands'
Beleza até aqui?
Agora quero adicionar um teste que valida a criação de um projeto com sucesso (via API).
Vejamos a implementação do teste.
const faker = require('faker')
describe('Create project', () => {
beforeEach(() => cy.api_deleteProjects()) // Falarei do método beforeEach em outro post.
it('successfully', () => {
const project = {
name: faker.random.word() // Vou aboardar o uso do faker em outro post também, explicando seu uso.
}
cy.api_createProject(project).then(response => {
expect(response.status).to.equal(201)
expect(response.body.name).to.equal(project.name)
})
})
})
E a implementação da App action (ou do comandos customizado que cria tal recurso via chamada de API).
const accessToken = Cypress.env('gitlab_access_token')
Cypress.Commands.add('api_createProject', project => cy.request({
method: 'POST',
url: `/api/v4/projects/?private_token=${accessToken}`,
body: { name: project.name }
})
Para criar um comando customizado, use a função .add, do módulo Cypress.Commands, onde o primeiro argumento é o nome do comando customizado, por exemplo, api_createProject; e o segundo argumento é a função de callback que implementa a lógica para fazer o que o comando customizado deve fazer.
No caso do comando customizado api_createProject, ele recebe um objeto project como argumento e executa o comando cy.request para criar tal recurso por meio de uma chamada de API, utilizando o atributo name do objeto project.
Além disso, ele usa a variável accessToken, definida fora do comando customizado, permitindo fazer a chamada à API.
Ok, a parte de testes de API está coberta.
Agora, vejamos um exemplo de um teste de GUI, também para a criação de um projeto.
const faker = require('faker')
describe('Create project', () => {
beforeEach(() => {
cy.api_deleteProjects()
cy.sessionLogin()
})
it('successfull', () => {
const project = {
name: faker.random.uuid(),
description: faker.random.words(5)
}
cy.gui_createProject(project)
cy.url().should(
'be.equal',
`Cypress.config('baseUrl')${Cypress.env('user_name')}/${project.name}`
)
cy.contains(project.name).should('be.visible')
cy.contains(project.description).should('be.visible')
})
})
E a implementação do comando customizado gui_createProject.
Cypress.Commands.add('gui_createProject', project => {
cy.visit('projects/new')
cy.get('#project_name').type(project.name)
cy.get('#project_description').type(project.description)
cy.get('.qa-initialize-with-readme-checkbox').check()
cy.contains('Create project').click()
})
Da mesma forma que o comando customizado api_createProject, o comando customizado gui_createProject também é definido pela função .add do módulo Cypress.Commands; ele também recebe um objeto project como argumento, mas sua implementação usa comandos Cypress que interagem com a aplicação como os usuários fariam, como cy.visit(), cy.get(…).type(…), cy. contains(…).click(), etc.
Observe que ele usa os atributos name e description do project para digitação nos campos de entrada de texto.
Pronto! Agora temos a funcionalidade de criação de projeto coberta tanto à nível de API, como de GUI!
Para obter detalhes sobre os comandos customizados api_deleteProjects e sessionLogin, leia o código do projeto.
Este conteúdo foi traduzido para inglês e pode ser encontrado no DEV Community.
O que está achando da série?
Aguardo teu feedback.
Ficou curioso(a) e quer aprender mais sobre automação de testes com Cypress? Conheça os cursos da Escola TAT.
- Cypress, do Zero à Nuvem
- Cypress intermediário
- Cypress avançado
- Boas práticas em automação de testes com Cypress
- Testes end-to-end com Cypress
Bons testes! 🎉
Tem alguma forma desses comandos me retornarem um valor, algo como uma função faria dando um return?
Oi brendon, recomendo fazer o curso Cypress Fundamentals, a partir do seguinte site e você vai entender melhor como o Cypress funciona.
Segue o link https://learn.cypress.io/.
Walmyr,
É uma boa manter gui_ e api_ como convenção no começo dos nomes dos Commands?
Esta é só uma opção. Pode usar camelCase também. O importante é manter a consistência. Definir um padrão e seguí-lo.