CI ready e2e testes para Angular com Cypress e TypeScript em menos de 60 minutos

Este artigo visa descrever como você pode configurar testes end-to-end para Angular com Cypress incluindo TypeScript. Você vai escrever seus primeiros testes do e2e e deixá-los prontos para rodar em um CircleCI como um sistema de integração contínua com cada atualização do seu repositório.

Teste de ponta a ponta (curto e2e) é um tipo de teste de software que valida o sistema de software juntamente com sua integração com interfaces externas. O objetivo do teste de ponta a ponta é exercitar um cenário de produção completo.

Source: https://www.guru99.com/end-to-end-testing.html.

Visão Geral

  • O que é Cypress?
  • Prerequisitos
  • Configurando o Cypress
  • Escrever alguns testes
  • Configurando a integração contínua
  • Conclusão e Referências

Eu tenho um background de desenvolvimento frontend na Microsoft .NET & WPF e lembre-se dos tempos em que avaliávamos frameworks caros para escrever testes end-to-end para nossos projetos. Depois de muitas avaliações e semanas, mesmo meses de código de cola personalizado e desenvolvimento de infra-estruturas de teste em cima das ferramentas existentes, finalmente temos alguns testes do e2e em execução. Eles foram frágeis, muitas vezes falharam por causa de ajustes manuais que tivemos que fazer ou problemas com corredores defeituosos no pipeline de integração contínua.

Alguns anos depois com Angular e Protractor como padrão para testes do e2e, ainda estávamos baseados em objetos de página, Selenium Web Driver e os testes continuaram a ser bastante pouco confiáveis. Não eram necessários frameworks comerciais caros e infra-estrutura personalizada. Mas foi divertido escrever os testes do e2e? No.

No entanto estamos em 2020 agora e chegou a hora de novos heróis surgirem. 🚀

O que é o Cypress?

Cypress promete testes rápidos, fáceis e confiáveis para qualquer coisa que roda em um navegador. Não é baseado no Selenium Web Driver que está usando conexões de rede para interagir com o seu navegador. Em vez disso Cypress é um test runner que roda dentro do seu navegador ao lado da sua aplicação web e, portanto, tem controle direto sobre ele.

Sem entrar em todos os detalhes, isso não só torna o Cypress mais rápido e confiável, mas também abre a porta para muitas outras características interessantes como

  • depuração de viagens no tempo,
  • snapshot e gravação fáceis,
  • espera automática.

Em cima de todas as características, o Cypress tem uma experiência de desenvolvimento (DX) que é quase inigualável. Você já viu uma mensagem nos logs de erros da sua construção falhada que diz exatamente o que você fez de errado, aponta para as dependências certas para adicionar e também links para um site de documentação explicativa descrevendo o problema? Isto é como o Cypress se sente. Ele é construído por desenvolvedores para desenvolvedores.

Cypress erro no servidor de construção dizendo-lhe como corrigi-lo

A seguir, vamos instalar o Cypress para um novo projeto Angular criado com a CLI. Iremos escrever alguns testes do e2e e concluir com a execução destes por um sistema de compilação automatizado. Todos estes passos não devem demorar mais de 60 minutos. Tentamos manter os passos tão curtos quanto possível, alavancando ferramentas existentes como Esquema Angular, bibliotecas e modelos comuns.

Pré-requisitos

Este guia assume que você tem um projeto de aplicação Angular 9 padrão. Se não, você pode criar um como você normalmente faria com o Angular CLI. Se você não tiver a CLI instalada globalmente, você pode fazer uso do comando npx que o instalará temporariamente no fly:

npx @angular/cli new <app-name>

Configurar o Cypress

Para configurar o Cypress junto com o TypeScript o mais rápido possível, nós fazemos uso de um esquema existente desenvolvido pelo BrieBug.

Na raiz do seu projeto Angular, você pode abrir o terminal e digitar o seguinte comando:

ng add @briebug/cypress-schematic --addCypressTestScripts

Se o CLI não estiver instalado globalmente, o comando ng pode não estar disponível diretamente. Você pode fazer com que o uso do ng local seja obrigatório a partir do comando package.json:

npm run ng -- add @briebug/cypress-schematic # In case 'ng' could not be found

Podemos remover o transferidor com segurança porque ele será completamente substituído. Durante a instalação alguns binários foram baixados porque o Cypress vem com uma IU com Electron como um corredor de teste interativo.

Utilizando a bandeira --addCypressTestScripts Dois práticos scripts npm foram adicionados para tornar o trabalho com o Cypress mais confortável. Um para executar o e2e testa sem cabeça e o outro script executando os testes com o Cypress UI runner:

 // package.json scripts "cy:run": "cypress run", "cy:open": "cypress open"

Se você executasse um desses scripts autônomos, o teste falharia porque ele tenta rotear para http://localhost:4200 onde nada é servido no momento. Para corrigir isso, precisamos abrir um segundo terminal e servir nossa aplicação Angular antes com npm start.

Felizmente o esquema ajustou o comando e2e para que isso seja feito automaticamente pelo construtor da CLI. Você pode servir a aplicação e iniciar o teste e2e usando o seguinte comando:

npm run e2e

Cypress irá detectar que nós o lançamos pela primeira vez. Ele verifica a sua instalação e adiciona alguns arquivos de exemplo iniciais. Após a IU ter aberto, podemos ver um teste que já foi criado para nós.

Cypress UI após cy:open

Selecting the test will run it. Inicialmente o teste falhará porque nós não testamos algo propriamente dito. Vamos corrigir isso agora.

Failing test that is not implemented yet

Writing Some Tests

Como um primeiro passo, como proposto pelas melhores práticas da Cypress, definimos nossa baseUrl global, para que não tenhamos que duplicar isso em cada execução de teste. Adicione o seguinte à configuração cypress.json:

// cypress.json{ "baseUrl": "http://localhost:4200"}

Depois disso, nós escrevemos nosso primeiro teste de fumaça que verifica apenas se o título padrão da aplicação está definido na página inicial Angular. Portanto, altere o conteúdo do spec.ts para o seguinte conteúdo:

// spec.tsit('smoke test', () => { cy.visit('/'); cy.contains('cypress-e2e-testing-angular app is running!');});

O teste começa roteando para a nossa baseUrl e prossegue consultando qualquer elemento que contenha o texto cypress-e2e-testing-angular app está rodando!.

Testando fluxos de usuários

Este teste já deve funcionar, mas vamos escrever alguns mais interativos. Como o e2e é inerentemente mais lento que os testes unitários, é totalmente bom ter testes e2e que modelam todo o fluxo do usuário para um recurso.

Por exemplo, queremos verificar se algumas características da página inicial são válidas: Nossa página deve conter o título e o texto ng generate no terminal por padrão, mas quando os usuários clicam no botão Material Angular, queremos garantir que o comando apropriado ng add seja exibido na visualização do terminal abaixo.

Você pode substituir o conteúdo do seu arquivo de teste por este:

// spec.tsdescribe('When Angular starting page is loaded', () => { beforeEach(() => { cy.visit('/'); }); it('has app title, shows proper command by default and reacts on command changes', () => { cy.contains('cypress-e2e-testing-angular'); cy.contains('.terminal', 'ng generate component xyz'); cy.contains('Angular Material').click(); cy.contains('.terminal', 'ng add @angular/material'); });});

Refatoramos nosso conjunto de testes adicionando um bloco describe para capturar todos os testes que rodam quando a página inicial é carregada. Como nós visitamos a baseUrl toda vez, nós movemos isto para a chamada beforeEach. Finalmente combinamos os testes básicos de fumaça com o teste para a visualização do terminal na página inicial.

É importante saber que você não deve armazenar os resultados da consulta do Cypress em variáveis, mas sim trabalhar com fechamentos. Além disso, nós selecionamos elementos por classes CSS e conteúdo de texto, que podem ser muito frágeis. É recomendável usar data- atributos para selecionar elementos.

Cypress tem muitas características e possibilidades. Não vamos cobrir todas elas porque nosso objetivo é focar logo no primeiro ponto de partida. A documentação oficial é realmente boa e cobre tudo sobre como interagir com os elementos.

Se você reexecutar esta suíte de testes, você deve ver a IU clicando em cada cenário e os três testes devem passar desta vez. ✔✔✔

Executar o nosso primeiro conjunto de testes Cypress com sucesso

Configurando a Integração Contínua

Agora os nossos testes sejam executados localmente, vamos dar o pontapé de saída de um pequeno pipeline CI (integração contínua). Uma boa maneira de se preparar para isso, é criar scripts npm e combiná-los para que o sistema de compilação possa usar um único script como ponto de entrada. Seguindo este método, você pode tentar os passos do CI localmente antes de empurrar on-line. Além disso, os scripts npm são bastante independentes de qualquer sistema de compilação real.

Em CI, precisamos iniciar nosso servidor em segundo plano e esperar que ele empacote nossa aplicação, o que pode levar algum tempo. Então precisamos iniciar o Cypress test runner, passar pelos testes e desligar o servidor quando os testes terminarem. Felizmente podemos fazer tudo isso com um único utilitário chamado start-server-and-test como descrito nos documentos do Cypress:

npm install --save-dev start-server-and-test

Após isso ser instalado, usamos o servidor Angular que está atualmente atrás de npm start e o combinamos com o comando headless cy:run:

 // package.json scripts "start": "ng serve", "cy:run": "cypress run", "e2e:ci": "start-server-and-test start http://localhost:4200 cy:run"

Você certamente poderia usar um build de produção ou build antes e servir o aplicativo usando qualquer servidor http. Por uma questão de concisão, vou deixar estas melhorias para você.

Circle CI

Para o nosso exemplo, escolhemos CircleCI porque ele se integra muito bem com o GitHub, é comumente usado lá e tem um plano livre. Você pode usar qualquer outro sistema CI como Jenkins ou GitLab (com o qual eu tenho mais experiência). Após entrar no CircleCI e conectar-se à nossa conta GitHub, você pode selecionar o repositório e criar um novo projeto através de seu painel de controle.

Para configurar o pipeline, você pode escrever um config.yml selecionando um template e ajustando-o às suas necessidades e eventualmente rodando o script do e2e. Felizmente o Cypress tem uma configuração pronta para uso (chamada Orbs) para o CircleCI que já inclui a instalação de dependências, caching e assim por diante. Antes de podermos usá-lo, devemos visitar as Configurações de Organização para habilitar terceiros executantes.

# circleci/config.ymlversion: 2.1orbs: # This Orb includes the following: # - checkout current repository # - npm install with caching # - start the server # - wait for the server to respond # - run Cypress tests # - store videos and screenshots as artifacts on CircleCI cypress: cypress-io/cypress@1workflows: build: jobs: - cypress/run: start: npm start wait-on: 'http://localhost:4200' store_artifacts: true

O pipeline só tem um trabalho: Executar todos os testes do e2e. Ele verifica o ramo atual, instala todas as dependências incluindo o cache, inicia o servidor de aplicações e executa os nossos testes. Além disso, vídeos (gravados por padrão) e screenshots (caso os testes estejam falhando) são carregados como artefatos CircleCI para inspeção posterior.*

CircleCI Dashboard

Conclusão

Os passos neste guia são bastante mínimos. Você pode usar seu projeto Angular existente, pode alterar a configuração de suas suítes de testes Cypress e escrever muitos testes mais significativos. Além disso, você pode definir scripts npm para diferentes cenários e ambientes e, é claro, todo o seu pipeline de construção pode ser estendido com a impressão, testes unitários, construção e até mesmo a implantação de sua aplicação. No entanto, este deve ser um primeiro passo que mostra como testes automatizados de ponta a ponta podem ser configurados rapidamente nos dias de hoje.

Espere até você escrever testes Cypress reais para sua aplicação. Você se divertirá!

Mente soprada gif

Espero que você também encontre algum valor neste artigo. Se você tiver alguma pergunta ou comentário, apenas me avise. Seu feedback é muito bem-vindo!

Você pode encontrar as fontes para este guia em GitHub:

MrCube42 / cypress-e2e-testing-angular

Exemplo de aplicação Angular 9 usando Cypress para testes de ponta a ponta.

CypressE2eTestingAngular

Este projecto foi gerado com Angular CLI versão 9.0.6.

Servidor de desenvolvimento

Exemplo de servidor de desenvolvimento ng serve para um servidor de desenvolvimento. Navegue até http://localhost:4200/. O aplicativo será automaticamente recarregado se você alterar qualquer um dos arquivos fonte.

Code scaffolding

Executar ng generate component component-name para gerar um novo componente. Você também pode usar ng generate directive|pipe|service|class|guard|interface|enum|module.

Build

Executar ng build para construir o projeto. Os artefatos de construção serão armazenados no diretório dist/. Use a bandeira --prod para um build de produção.

Executar testes unitários

Executar ng test para executar os testes unitários via Karma.

Executar testes de ponta a ponta

Executar npm run e2e para executar os testes de ponta a ponta via Cypress.

Outras ajudas

Para obter mais ajuda sobre o uso da CLI Angular ng help ou vá verificar o README da CLI Angular.

Leave a Reply