10 Boas Práticas essenciais para o seu dia a dia com o Cypress

Gisele Rosa
stonetech
Published in
9 min readMar 10, 2021

Recentemente tive a oportunidade de estudar e começar a automatizar os testes de alguns projetos que eu estava envolvida utilizando o Cypress, e no decorrer dos dias de trabalho e estudo selecionei algumas boas práticas que foram utilizadas nesses projetos. E por tal motivo, decidi fazer esse post para compartilhar com vocês esse aprendizado.

Abaixo você encontrará dicas de organização de testes, seleção de elementos, uso de variáveis de ambiente, espera inteligente, configurações entre outros temas. Tentando trazer alguns exemplos práticos para que fique mais fácil o entendimento.

1 — Organização de testes, login, estado de controle

Um dos cenários que nos deparamos diariamente é com a decisão de organização dos nossos testes, manipulação de login e diferentes estados da aplicação. Vamos a algumas práticas que a equipe do Cypress recomenda com relação a esse tema.

Prática Não Recomendada:

  • Compartilhamento de objetos de página, usando sua UI para fazer login e não usando atalhos

Prática recomendada:

  • Teste as especificações isoladamente
  • Faça os logins de forma programática com controle e visibilidade
  • Busque fazer controle do estado do aplicativo

Existem vários recursos no Cypress que podem auxiliar nessas práticas e também é possível o uso dos Asserts.

Nesse link é possível ver diversos exemplos login criado pela própria equipe do Cypress.

2 — Seleção de elementos

O Cypress tem um recurso chamado Selector Playground ele permite que você inspecione os elementos do DOM e possa obter comando como get(), e debugar em tempo de execução os testes. Entretanto, ele só funciona perfeitamente se usada a boa prática recomendada, sendo assim para que o mesmo funcione perfeitamente é necessário usar o atributo data-* e isolá-los das alterações de css e js. Mas sabemos que em alguns cenários isso não é a realidade.

Entretanto, mesmo que por não ter acesso ao source ou o projeto não ter sido projetados com esses atributos é possível usar css selector e até mesmo xpath. Eu particularmente recomendaria o uso de css selector.

Após alguns testes de uso foi possível entender um pouco melhor como funciona essa captura de elementos e existe uma hierarquia de prioridade. O Selector Playground tem preferência por alguns elementos como:

  • data-cy
  • data-test
  • data-testid
  • id
  • class
  • tag
  • attributes
  • nth-child

Mas vale ressaltar atenção quando estiverem montando seus seletores, pois é de extrema importância que eles sejam únicos evitando intermitência, quebras e falhas nos testes. E como boa prática façam sempre validações. E reforço também que uma das boas práticas que a ferramenta prega é o uso do data-cy.

Mas, porquê o data-cy?

Quando usamos um atributo como o data-* estamos fornecendo um contexto aos nossos seletores de automação, e dessa forma qualquer alteração de CSS ou JS não irá impactar no nosso código de automação. Elementos resilientes a alteração da aplicação são sempre mais recomendados.

E no Cypress eles recomendam o uso de data-cy para identificar os atributos de automação para os elementos de DOM. Fazendo isso, automaticamente o Selector Playground isola o elemento e identifica o seletor e faz a inspeção de acordo com a hierarquia apresentada.

Agora partiu ver um exemplo de código? Bora colocar a mão na massa? Ops, no código?

Dado um botão com o qual queremos interagir:

Vamos investigar como podemos identificá-lo de forma única em um seletor, vendo diferentes formas e analisando se ela é ou não recomendada e o motivo:

3 — Uso de variáveis

No Cypress não precisará usar sempre const, let ou var. Ao usar fechamentos (closures), você sempre terá acesso aos objetos que foram cedidos a você sem atribuí-los.

A única exceção a essa regra é quando você está lidando com objetos mutáveis ​​(que mudam de estado). Quando as coisas mudam de estado, você geralmente deseja comparar o valor anterior de um objeto com o próximo valor.

Este é um ótimo caso de uso para a const.

4 — Teste apenas o que você controla

No documentação do Cypress é recomendado que evitemos depender de servidores de terceiros. Quando isso ocorrer e for necessário, devemos utilizar o cy.request() para a comunicação com os servidores externos através de suas APIs.

Motivos:

  • É extremamente demorado e torna seus testes mais lentos
  • O site de terceiros pode ter alterado ou atualizado seu conteúdo
  • O site de terceiros pode estar tendo problemas fora do seu controle
  • O site de terceiros pode detectar que você está testando por meio de um script e bloqueá-lo.
  • O site de terceiros pode estar executando campanhas A / B e irá causando problemas no script

5 — Independência nos testes

Os testes devem sempre ser executados independentemente um do outro e ainda assim serem aprovados.

Você só precisa fazer uma coisa para saber se acoplou seus testes incorretamente ou se um teste está contando com o estado de um anterior.

Faça um .only no seu teste e rode o mesmo novamente.

Se este teste puder ser executado sozinho e passar — parabéns, você escreveu um bom teste.

Se este não for o caso, você deve refatorar e alterar sua abordagem.

Como resolver isso:

  • Mova o código repetido em testes anteriores para before ou beforeEach
  • Combine vários testes em um teste maior

6 — Usando after ou afterEach

Limpe o estado antes da execução dos testes, use os Hooks a favor do seu teste.

Se você deseja executar algumas etapas apenas uma vez após todos os casos de teste terem concluído sua execução, você pode usar o bloco after () para agrupar todas essas etapas de teste. Ele pode conter algumas etapas de desmontagem que precisam ser realizadas após o término da execução de todos os casos de teste, como por exemplo limpar o localStorage, Cookies e etc

E no caso de você desejar executar algumas etapas após cada um dos casos de teste no TestSuite ter concluído sua execução, você pode usar o bloco afterEach() para agrupar todas essas etapas de teste também. Ele pode conter algumas etapas de desmontagem que precisam ser realizadas após o término da execução de cada um dos casos de teste. Pode ser algo como colocar o aplicativo ou banco de dados em um estado específico após cada caso de teste.

7 — Use espera de forma consciente

Evite : Espera por períodos de tempo arbitrários usando cy.wait(Number).

Prática recomendada: use aliases de rota ou asserções para impedir que o Cypress prossiga até que uma condição explícita seja atendida.

No Cypress, você quase nunca precisa usar cy.wait(). Se você estiver fazendo isso, provavelmente existe uma maneira muito mais simples ou existe alguma lentidão no ambiente que precisa de atenção.

Vamos imaginar os seguintes exemplos:

Espera desnecessária por cy.request()

Se você usa o cy.request() utilizar espera aqui é desnecessário, pois o comando não será resolvido até receber uma resposta de seu servidor. Adicionar a espera aqui apenas adiciona 5 segundos depois que o cy.request()já foi resolvido.

Espera desnecessária por cy.visit()

Esperar por isso é desnecessário porque é cy.visit() resolvido assim que a página dispara seu load evento. Nesse momento, todos os seus ativos foram carregados, incluindo javascript, css e html.

Espera desnecessária por cy.get()

A espera pelo cy.get() seguinte é desnecessária, porque o cy.get() automaticamente faz novas tentativas até que a tabela tr tenha um comprimento de 2.

Sempre que os comandos têm uma asserção, eles não serão resolvidos até que suas asserções associadas sejam aprovadas. Isso permite que você descreva o estado do seu aplicativo sem se preocupar com quando ele chegará lá.

Alternativamente, uma melhor solução para esse problema é esperar explicitamente por uma rota com alias.

8 — Configurando um baseUrl global

Defina a baseUrl em seu seu arquivo de configuração cypress.json.

Adicionar um baseUrl em sua configuração permite que você omita a passagem baseUrl de comandos como cy.visit() e cy.request(). O Cypress assume que este é o url que você deseja usar.

Adicionar um baseUrl também pode economizar algum tempo durante a inicialização dos testes Cypress.

Quando você começa a executar seus testes, o Cypress não sabe a url do aplicativo que você planeja testar. Portanto, o Cypress inicialmente abre em https://localhost uma porta + aleatória.

9 — Definir variáveis de ambiente

Existem diferentes formas de definir variáveis de ambiente. Cada uma delas tem um caso de uso ligeiramente diferente. E nesse tutorial vamos nos concentrar em duas opções: configuration file e cypress.env.json. Você não deve se sentir obrigado a escolher apenas um método, inclusive na documentação você terá acesso a outros métodos.

Quando você executa seus testes, você pode usar a função Cypress.env para acessar os valores de suas variáveis de ambiente.

Opção nº 1 Arquivo de configuração

Qualquer par de chave/valor que você definir em seu arquivo de configuração (cypress.json por padrão) na chave env se tornará uma variável de ambiente.

E no arquivo de teste você chamará as variáveis da seguinte maneira:

Benefícios

Essa opção é ótima para valores que precisam ser verificados no controle de origem e permanecem os mesmos em todas as máquinas.

Desvantagens

A desvantagem dessa opção é que ela só funciona para valores que devem ser iguais em todas as máquinas.

Opção nº 2 cypress.env.json

Alternativamente, você pode decidir criar seu próprio arquivo cypress.env.json que o Cypress verificará automaticamente. Os valores neste arquivo sobrescreverão variáveis de ambiente conflitantes em seu arquivo de configuração (cypress.json por padrão).

Esta é uma estratégia muito útil porque, se você adicionar cypress.env.json ao seu arquivo .gitignore, os valores no arquivo podem ser diferentes para cada máquina de desenvolvedor ou ambiente sem nenhum problema.

E no arquivo de teste você chamará as variáveis da seguinte maneira:

Existem outras formas também CLI, variáveis dos plugins, variável de configuração de testes. Mas essas duas formas foram as que me deram mas liberdade de configuração de forma organizada e simples.

Benefícios:

  • Esta opção fornece um arquivo dedicado apenas para variáveis de ambiente.
  • Isso permitirá que você gere este arquivo a partir de outros processos de construção.
  • Os valores podem ser diferentes em cada máquina (se não for verificado no controle de origem).
  • Esta opção suporta campos aninhados (objetos), por exemplo, {testUser: {nome: ‘…’, email: ‘…’}}.

Desvantagens

  • Este é outro arquivo com o qual você tem que lidar.
  • Pode ser um exagero para 1 ou 2 variáveis de ambiente.

10 — Utilize Linters

Linters são ferramentas de depuração que ajudam a padronizar os códigos do projeto, por exemplo: Se tiver uma equipe com umas 30 pessoas que pensam diferente, têm gostos e práticas diferentes, como fazer eles programarem no mesmo padrão? Será que é possível? Sim! Utilizando um linter. E existem alguns hoje, no caso da nossa equipe por exemplo utilizamos o ES Lint.

Mas a equipe do Cypress também desenvolveu um plugin de linter que vale a pena dar uma olhada. Ele é um ESLint para testes em Cypress, e nele são reforçadas as regras de melhores Práticas recomendadas pelo Cypress.

--

--