Что нового
  • Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Testes e2e em React com Cypress

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,674
Баллы
155
Introdução


No

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

do mês de setembro, escrevi sobre como configurar Cypress para ser possível realizar testes end-to-end em React e mostrei duas formas de executar eles (via interface e via terminal). A ideia agora é mostrar como funciona a realização dos testes, com alguns conceitos e exemplos.

Estrutura testes


A estrutura dos testes segue da seguinte forma:

  • describe: vai representar o bloco de testes a ser executado, podendo ser referente a um contexto ou fluxo específico
  • it: vai representar o teste que vai ser executado, que vai seguir as seguintes etapas
    1. acessar a página onde vai começar o teste
    2. buscar um elemento HTML dentro da tela
    3. interagir com elemento buscado
    4. definir uma expectativa para o teste

describe("Descrição bloco", () => {
it("descrição teste", () => {
acesso da página
busca de elemento na tela
interação com elemento

expectativa do teste
})

it("descrição outro teste", () => {
(…)
})
})

Aqui está exemplificado uma busca, uma interação de elemento e uma expectativa no teste, mas é possível realizar múltiplas dentro dele.

Acesso da página


Para acessar uma página será usado cy.visit(), que permite acessar uma url, que vai ser o ponto de partida dos testes.

Busca de elemento na tela


Para a busca de elementos HTML existem diferentes formas disponíveis, seguem alguns exemplos:

QueryBuscaCódigo
containspelo textocontains(text)
getpelo seletorget(selector)

A busca por get pode ser realizada de diversas formas:

BuscaExemplo
pelo data-cycy.get('[data-cy="example"]')
pelo namecy.get('[name="submit"]')
pelo idcy.get('#main')
pelo classNamecy.get('.btn')
pela role (função)cy.get('button')

O data-cy corresponde a uma definição no elemento exclusiva para localizá-lo nos testes.

Interação com elemento


Após a busca do elemento na página é possível interagir com ele, seguem algumas formas disponíveis:

InteraçãoAção
click()clique
dblclick()clique duplo
type()escrita de texto
check()seleciona checkbox/radio button
uncheck()deseleciona checkbox
submit()submeter um form
Expectativa do teste


Para definir a expectativa do teste será usado should(), que possui alias and(), que permite fazer a validação dos testes, seguem algumas formas disponíveis:

ExpectativaValidação
should('have.value', value)valor
should('be.enabled')está habilitado
should('be.disabled')está desabilitado
should('contain', text)texto
should('have.length', length)tamanho
should('exist')existência
should('include')inclusão

Para validar a negação das expectativas seria colocar not. como primeira parte dentro do should, por exemplo should('not.exist').

Execução dos testes


No artigo do mês passado, que o link está na introdução desse artigo, foram definidas duas formas de executar os testes em package.json, pela interface e pelo terminal:


{
"scripts": {
//...
"cy:open": "cypress open", // interface
"cy:run": "cypress run" // terminal
}
}

Para execução dos testes localmente em Cypress, é necessário primeiro executar a aplicação localmente em um terminal, depois executar os testes em outro terminal.
Sendo uma mesma porta definida quando se sobe a app local e para evitar sempre escrever o mesmo começo na primeira etapa de todos os testes (partindo por exemplo da porta 3000), é possível definir em cypress.config.js:


const { defineConfig } = require('cypress')

module.exports = defineConfig({
e2e: {
baseUrl: '

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

',
},
})

Dessa forma todo teste que começar com cy.visit('/') estará partindo da página

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.
Observação: no caso de executar em pipelines de ambientes de teste, seria colocar uma ENV em baseUrl para acessar a url esperada relacionada ao ambiente que for rodado os testes.

Exemplos de testes


Para os exemplos apresentados será usada a página de exemplo que o próprio Cypress disponibiliza:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


Que vai representar, para o artigo aqui, como se fosse a url referente a aplicação rodando no terminal localmente.
Como todos os exemplos vão partir dessa url, em cypress.config.js será colocada ela como baseUrl:


const { defineConfig } = require('cypress')

module.exports = defineConfig({
e2e: {
baseUrl: '

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

',
},
})

A ideia é trazer exemplos mais simples para mostrar um pouco de cada etapa que compõe a escrita dos testes, mas na prática o Cypress quando é utilizado para validação de testes de ponta a ponta, os testes costumam ser mais complexos e terem bem mais interações dentro deles.

Teste de presença


Nesse primeiro teste vai ser analisado após clicar em um link na página de exemplo do Cypress, se chegou na página esperada (fazendo uma expectativa em cima da url) e se tem alguns elementos presentes na tela.
Primeiro vai ser colocado o arquivo dentro da pasta cypress/e2e, que é onde o Cypress vai buscar os testes para serem executados, definindo o arquivo presence.cy.js:


describe('Presence tests', () => {
beforeEach(() => {
cy.visit('/')

cy.contains('get').click()
})

it('reach expected page', () => {
cy.url().should('include', '/commands/querying')
})

it('has queries options', () => {
cy.get('#querying').should('contain', 'get()')
.and('contain', 'contains()')
.and('contain', 'within()')
.and('contain', 'root()')
})
})

Para esse bloco de teste está se começando acessando a página inicial de exemplo do Cypress, buscando o link que possui texto get e clicando nele. Como todos os testes do bloco tem o mesmo começo, essa parte foi colocada dentro de um beforeEach antes dos testes.
Se espera no primeiro teste que a página que chegar inclua na url /commands/querying e no segundo teste que se tenha na tela as diferentes queries disponíveis, validando pelo texto delas.

Executando no terminal yarn cy:run, retorna as informações do resultado dos testes que vou quebrar em pedaços para explicar abaixo.
Primeiro é mostrado as informações da execução, com versão do Cypress utilizada, o browser, a versão do node, a quantidade de arquivos de teste e onde foram buscados:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Depois é mostrado o arquivo que foi executado, o bloco de testes e os testes que foram realizados (com um positivo do lado mostrando que passou o teste), com a quantidade dos que passaram:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Após é mostrado um caixa com os resultados dos testes, com a quantidade de testes executados, quantos passaram, quantos falharam, quantos estão pendentes, quantos foram dado skip, quantos geraram screenshots, se foi gerado vídeo, a duração dos testes e por fim o arquivo executado:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



E por fim, uma tabela com o arquivo executado, tempo de execução, quantidades de testes, quantos passaram, quantos falharam, quantos estão pendentes e quantos foram dado skip. Como todos os testes passaram, vem uma mensagem All specs passed!:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Uma outra forma de executar os testes é via interface, seguindo os seguintes passos:

  • Executar yarn cy:open
  • Escolher a caixa E2E Testing
  • Escolher o navegador de preferência
  • Clicar em Start E2E Testing
  • Clicar no arquivo que deseja executar
  • Aguardar a execução dos testes


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Durante a execução será mostrado do lado direito a navegação acontecendo de acordo com os testes.
Finalizada a execução, do lado esquerdo aparecerá o bloco que foi executado e os testes, como nesse caso eles passaram vai ter um positivo do lado deles. Do lado direito onde parou ao final das execuções:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Do lado esquerdo é possível abrir um dos testes e passar o mouse em cada parte que executou dentro do teste e ver do lado direito onde estava durante a navegação:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Agora simulando uma falha no segundo teste do bloco, modificando uma das expectativas, rodando pelo terminal terá algumas diferenças na visualização do resultado.
Será mostrado o teste dentro do bloco que falhou (destacado em vermelho), que um teste passou e outro teve falha, e onde especificamente a falha aconteceu:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



A parte de resultados vai estar destacado em vermelho, informando que um teste falhou e que foi criado um screenshot mostrando como estava a tela no momento da falha:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



E por fim será mostrado em uma tabela que de dois testes, um passou e um falhou. Com o destaque no final em vermelho que 1 of 1 failed (100%). Essa informação corresponde a quantos blocos de testes falharam, não os testes em si. Como o bloco Presence tests teve um teste falhando dentro dele, isso já faz o bloco ser considerado com falha:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



No caso da execução via interface, vai ser mostrado onde especificamente o teste falhou com a imagem ao lado:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Teste múltiplas interações


Nesse teste vai ser analisado após clicar no link type na página de exemplo do Cypress, se chegou na página esperada (fazendo uma expectativa em cima da url) e após escrita de texto em um campo input se o valor dentro dele corresponde ao que foi escrito.
Vai ser colocado o arquivo dentro da pasta cypress/e2e, que é onde o Cypress vai buscar os testes para serem executados, definindo o arquivo actions.cy.js:


describe('Actions tests', () => {
beforeEach(() => {
cy.visit('/')

cy.contains('type').click()
})

it('reach expected page', () => {
cy.url().should('include', '/commands/actions')
})

it('fill email address', () => {
cy.contains('Email address').next().type('example@aloha.com')

cy.contains('Email address').next().should('have.value', 'example@aloha.com')
})
})

Nesse bloco de testes está sendo usado next(), que acessa o elemento html que está logo após ao que foi buscado. Dessa forma, é possível acessar o campo input para preencher, que está logo após o título buscado.
Após a execução, os testes passam com sucesso.

Boas práticas


A documentação do Cypress apresenta boas prática a serem seguidas durante os testes, vou apresentar algumas abaixo:

Definir um baseUrl global


Para testes que sempre começam pelo mesmo domínio, definir em cypress.config.js a baseUrl:


const { defineConfig } = require('cypress')

module.exports = defineConfig({
e2e: {
baseUrl:,
},
})
Usar beforeEach para códigos compartilhados entre os testes


É recomendado colocar código compartilhado dentro de um beforeEach:


beforeEach(() => {
// código compartilhado
})
Realizar múltiplas expectativas em conjunto


Ao invés de separar expectativas em diferentes testes para um mesmo elemento, fazer expectativas múltiplas:


// Não recomendado
it('has get query option', () => {
cy.get('[data-cy="queries"]').should('contain', 'get()')
})

it('has within query option', () => {
cy.get('[data-cy="queries"]').should('contain', 'within()')
})

// Recomendado
it('has queries options', () => {
cy.get('[data-cy="queries"]').should('contain', 'get()')
.and('contain', 'within()')
})
Prioridade de busca de elementos


Esse pode ser um pouco polêmico, dado que a principal sugestão é adicionar um elemento exclusivo de localização de teste dentro do elemento HTML. Partindo do seguinte componente:


<button
id="example"
class="btn-primary"
name="submission"
role="button"
data-cy="primary"
>
Submit
</button>

Segue abaixo a ordem crescente de prioridade e os motivos apresentados na documentação:

SeletorRecomendadoMotivo
cy.get('button').click()NuncaO pior. Muito genérico, sem contexto
cy.get('.btn-primary').click()NuncaRuim. Acoplado com estilização e com grande probabilidade de mudança
cy.get('#example').click()Com moderaçãoMelhor. Mas ainda acoplado com estilização e event listeners em JS
cy.get('[name="submission"]').click()Com moderaçãoAcoplado com attributo name, que tem semântica HTML
cy.contains('Submit').click()DependeMuito melhor. Mas ainda acoplado a texto que pode ser modificado
cy.get('[data-cy="primary"]').click()SempreO Melhor. Isolado de mudanças
Conclusão


A ideia desse artigo foi trazer uma visão geral de como funciona os testes, abordando estrutura, acesso de página, busca de elemento HTML, interações e validações, com apresentação de exemplos e boas práticas que a documentação recomenda.
Mas são possíveis vários outros cenários de testes e formas de uso do Cypress, por essa razão estou colocando os principais links separados por tema para quem quiser se aprofundar mais.

Links



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх