# Automatização de Testes para CI/CD
## ℹ️ SOBRE A PESQUISA
Esta pesquisa foi elaborada pela gerente Andrieli Gonçalves, como parte de suas atividades durante seu mandato na diretoria de Qualidade, no período de 27 de maio a 10 de julho de 2024.
Com o objetivo de contribuir para o desenvolvimento dos trabalhos realizados pelos membros desta e de outras diretorias da Ecomp, foram estudados os seguintes temas: automatização de testes, princípios de Integração Contínua e Entrega Contínua (CI/CD), tipos de testes, ferramentas de automatização de testes e estratégias de uso/implementação dos conceitos citados anteriormente.
## 💻 INTRODUÇÃO À AUTOMATIZAÇÃO DE TESTES
### O que é um teste?
Em um contexto de desenvolvimento e garantia de qualidade de software, um teste é representado pelos passos de preparação de um cenário, execução da ação que se deseja testar e, por fim, verificação do resultado obtido — considerando o resultado esperado.
#### Problema de testes manuais
Embora a realização de testes seja extremamente importante para garantir a consistência e a integridade do projeto em desenvolvimento, quando estes são feitos manualmente — ou seja, dependem de uma ou mais pessoas para realizar alguma das suas três etapas (preparação, execução e verificação) —, múltiplos problemas podem permear tal situação, como a possibilidade de **erros humanos**, **a demora na detecção de falhas** e o **tempo elevado para a execução completa dos testes**.
Nesse sentido, para contornar possíveis impedimentos, surgem os **testes automatizados**.
### O que é um teste automatizado?
Um teste automatizado segue a mesma premissa de um teste manual. No entanto, como diferencial, ele é aplicado mediante o uso de uma **ferramenta de integração contínua de software**.
Para garantir a eficácia na automatização de testes, é importante investir na capacitação das pessoas envolvidas neste processo — dentre os assuntos que devem ser conhecidos, é possível salientar bibliotecas/funções de testes, padrões de código, relatórios de teste e logs de execução.
## 🔁 PRINCÍPIOS DE CI/CD
Em linhas gerais, a proposta da abordagem de CI/CD é aperfeiçoar o processo de **desenvolvimento de software**. CI/CD representa as práticas de **Integração Contínua (CI)** e **Entrega Contínua (CD)**, que visam automatizar a integração do código e a entrega de software, permitindo que equipes de desenvolvimento entreguem atualizações de forma mais rápida e segura.
Os principais objetivos do CI/CD são:
* **Automação de integração e entrega**, reduzindo o esforço manual e minimizando erros humanos;
* **Ciclo de desenvolvimento otimizado**, acelerando o processo de desenvolvimento e entrega de software;
* **Colaboração e consolidação de metodologias ágeis**, facilitando a comunicação e a colaboração dentro de uma equipe;
* **Promoção de testes automatizados**, garantindo que o código esteja sempre em um estado de alta qualidade;
* **Feedback contínuo**, fornecendo retornos rápidos aos desenvolvedores sobre as mudanças de código.
## 🤖 TIPOS DE TESTE
### Testes de unidade
São feitos em um nível mais baixo, próximos ao código-fonte do software. Buscam testar métodos/funções **individuais** de classes, componentes e módulos utilizados na aplicação. ***Exemplo: verificar se uma função que realiza determinado cálculo retorna o valor esperado.***
### Testes de integração
Seu foco é observar como diferentes partes de uma aplicação funcionam em conjunto. ***Exemplo: testar se o módulo de autenticação funciona corretamente em conjunto com o módulo de perfil de usuário.***
### Testes ponta-a-ponta
Simulam os fluxos de um usuário pelo software, verificando se funcionam como o esperado. ***Exemplo: Verificar se um usuário consegue se registrar, fazer login e compartilhar um comentário em um site.***
### Testes de aceitação
Seu foco é analisar se a aplicação cumpre todos os seus requisitos de negócios definidos anteriormente. ***Exemplo: Validar que todas as funcionalidades de um e-commerce, como adicionar itens ao carrinho e finalizar a compra, estão funcionando conforme os requisitos.***
### Testes de desempenho
Avaliam o desempenho do aplicativo estando diante de cenários específicos, como a entrada de uma quantidade exorbitante de dados. Isso ajuda a verificar sua velocidade e capacidade de resposta, por exemplo. ***Exemplo: Medir o tempo de resposta de uma API ao receber uma grande quantidade de solicitações simultâneas.***
## 🪄 FERRAMENTAS DE AUTOMATIZAÇÃO DE TESTES
### 💅 Front-end
#### [Jest](https://github.com/jestjs/jest)
Pensando no contexto da Ecomp, em que usamos tecnologias baseadas no JavaScript, como **Vue.js** e **React Native**, uma ferramenta super interessante para realização de testes é o framework Jest, que trabalha especificamente com **testes unitários**.
O Jest pode ser aplicado em múltiplos cenários, como na renderização de um **componente Vue.js**, na validação do **formato de datas** ou até mesmo no **disparo de uma função** de acordo com a **ação realizada pelo usuário**.
Siga os passos abaixo para implementá-lo em seu projeto. Lembre-se de acessar a pasta do Front-end!
1. Instalar o Jest:
```
npm install --save-dev jest jest-environment-jsdom babel-jest @babel/preset-env @vue/vue3-jest @vue/test-utils
```
* `jest`: Framework de testes;
* `jest-environment-jsdom`: Ambiente de teste que simula um navegador usando **JSDOM**;
* `babel-jest`: Permite que você use Babel para transpilar seu código antes dos testes;
* `@babel/preset-env`: Para compilar o JavaScript "moderno" para uma versão compatível com o ambiente de desenvolvimento;
* `@vue/vue3-jest`: Permite ao Jest compreender o funcionamento dos componentes do Vue 3;
* `@vue/test-utils`: Biblioteca de utilitários para testar componentes Vue.
2. Criar e definir as configurações do arquivo `jest.config.cjs`:
```cjs=
module.exports = {
testEnvironment: "jsdom",
transform: {
"^.+\\.vue$": "@vue/vue3-jest",
"^.+\\js$": "babel-jest",
},
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)$",
moduleFileExtensions: ["vue", "js"],
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1",
},
coveragePathIgnorePatterns: ["/node_modules/", "/tests/"],
coverageReporters: ["text", "json-summary"],
testEnvironmentOptions: {
customExportConditions: ["node", "node-addons"],
},
}
```
* **Linha 2:** Define o ambiente de teste para o `jsdom`, que simula um navegador do Node;
* **Linhas 3-6:** Configura os transformadores para arquivos de teste;
* **Linha 7:** Expressão regular pra localizar os arquivos de teste (aqueles com a extensão `.test` ou `.spec`);
* **Linha 8:** Define as extensões dos arquivos que o Jest precisa reconhecer e processar;
* **Linhas 9-11:** Mapeia módulos importador para diferentes arquivos;
* **Linha 12:** Define quais arquivos devem ser ignorados;
* **Linha 13:** Define quais os relatórios o Jest precisa gerar;
* **Linhas 14-16:** Configurações adicionais para o ambiente de teste.
3. Criar e definir as configurações do arquivo `babel.config.cjs`:
```cjs=
module.exports = {
env: {
test: {
presets: [
[
"@babel/preset-env",
{
targets: {
node: "current",
},
},
],
],
},
},
}
```
* **Linha 1:** Exporta a configuração do Babel;
* **Linhas 2-3:** Configura *presets* e *plugins* para o ambiente de teste;
* **Linha 4:** Define os *presets* que o Babel precisa usar para transformar o código;
* **Linha 6 em diante:** Indica que é possível usar a sintaxe atual do JavaScript e que ele será transformado para uma versão compatível do Node.
4. Atualizar o `package.json` adicionando `"test:unit": "jest"` na seção de `"scripts"`:
```
"scripts": {
...
"test:unit": "jest"
},
```
5. Na pasta de um dos seus componentes, criar um arquivo `nomeDoComponente.spec.js` e escrever seu teste
6. Executar o teste:
```
npm run unit:test
```
> ℹ️ Observação: note que, em alguns arquivos, foi necessário utilizar a extensão `.cjs` em vez de `.js` — talvez isso também seja necessário em seu projeto! O `.cjs` é o formato do CommonJS, que tem umas características extras com relação à sintaxe, permitindo uma maneira diferente de importar e exportar módulos.
#### [Vitest](https://github.com/vitest-dev/vitest)
Também voltado para testes unitários, nós temos o Vitest, recomendado para projetos baseados em Vite, como é o caso de muitos projetos Vue.js.
> ℹ️ Observação: o Vite é uma ferramenta de construção que atua em conjunto com frameworks JavaScript. Ele foi criado especificamente para o Vue.js, tendo como objetivo modificar a sua organização tradicional de servidores de **desenvolvimento** e de **produção**, concentrando-se apenas no primeiro.
> Acesse o [repositório do Vite](https://github.com/vitejs/vite?tab=readme-ov-file) para conhecê-lo um pouco mais.
Passo a passo para implementar a ferramenta em seu projeto:
1. Instalar o Vitest:
```
npm install -D --save-dev vitest @vitejs/plugin-vue
```
* `vitest`: Framework de testes;
* `@vitejs/plugin-vue`: Ajuda a corrigir problemas de sintaxe em arquivos `.vue`;
2. Criar e definir as configurações do arquivo `vite-config.js`:
3. Atualizar o `package.json` adicionando `"test:unit": "vitest"` na seção de `"scripts"`:
```
"scripts": {
...
"test:unit": "vitest"
},
```
4. Na pasta de um dos seus componentes, criar um arquivo `nomeDoTeste.spec.js` e escrever seu teste;
5. Executar o teste
```
npm run test:unit
```
#### [Cypress](https://github.com/cypress-io/cypress)
O Cypress é uma ferramenta de testes de ponta-a-ponta (E2E) baseada em Javascript que permite testar a aplicação do **ponto de vista do usuário**.
Geralmente, quando trabalhamos com Cypress, seguimos esta estrutura de pastas e arquivos:
* `📁 e2e (ou intregation)`: Inclui os arquivos de teste. Os padrões de extensão são `nomeDoTeste.spec.js` e `nomeDoTeste.cy.js`;
* `📁 fixtures`: Armazena dados de teste;
* `📁 plugins`: Contém um arquivo chamado `index.js`, o qual é importado todas as vezes antes de executar um arquivo de teste;
* `📁 screenshots`: Armazena captura de tela dos testes feitos;
* `📁 support`
* `🔗 commands.js`;
* `🔗 e2e.js (ou index.js)`;
* `📁 videos`: Possui vídeos de cada arquivo de teste após executá-los;
* `🔗 cypress.config.js`: Salvar configurações importantes do Cypress, como URL do projeto, timeouts etc.
Para integrar o Cypress a um projeto com Vue.js, basta seguir os passos abaixo:
1. Instalar o Cypress
```
npm install cypress --save-dev
```
2. Executar o comando `npx cypress open`
3. Na pasta do projeto, criar o arquivo `cypress.config.js` e adicionar uma configuração base, como esta:
```js=
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
},
baseUrl: 'http://localhost:3000',
supportFile: false,
},
})
```
* **Linha 1:** Importa a função de configuração `defineConfig` do módulo `cypress`;
* **Linha 3:** Exporta a configuração definida pelo Cypress;
* **Linha 4:** Inicia a definição da configuração para os testes E2E do Cypress;
* **Linha 5:** Definição da função `setupNodeEvents`, que pode guardar eventos relacionados ao Node.js;
* **Linha 7:** Indicação da URL base para os testes;
* **Linha 8:** Desativa o arquivo de suporte padrão do Cypress (o qual geralmente é executado antes da realização de qualquer teste).
4. Na pasta `cypress`, criar dentro de uma subpasta `e2e` um arquivo de teste `nomeDoTeste.spec.js` ou `nomeDoTeste.cy.js`
5. Dependendo das configurações do seu projeto, será importante modificar o arquivo `tsconfig.json`:
```json=
{
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"moduleResolution": "node"
}
}
```
* **Linha 2:** Indica que o arquivo `tsconfig.json` está herdando as configurações do arquivo `tsconfig.json` da pasta `.nuxt`;
* **Linha 3:** Define um objeto com configurações para o compilador do TypeScript;
* **Linha 4:** Define como o TypeScript trabalhará com módulos, levando-o a ter um padrão semelhante ao Node.js.
6. Executar o teste com `npx cypress run`.
### ⚙️ Back-end
#### [PHPUnit](https://github.com/sebastianbergmann/phpunit)
O PHPUnit é uma das ferramentas mais utilizadas para **testes unitários** em aplicações desenvolvidas com PHP, como é o caso de projetos que utilizam Laravel no Back-end.
Ele pode ser usado, por exemplo, para testar regras de validação, controladores e relacionamento de modelos.
1. Com o Composer, instalar o framework
```
composer require --dev phpunit/phpunit
```
2. Organizar o arquivo de configuração de teste `phpunit.xml`
3. Criar um diretório chamado `testes` e um arquivo `nomeDoTeste.php`
4. Executar o teste
```
./vendor/bin/phpunit
```
#### [Codeception](https://github.com/Codeception/Codeception)
O Codeception é um framework de teste BDD (*Behavior Driven Development* ou Desenvolvimento Orientado ao Comportamento) e de aceitação para PHP que oferece suporte a vários tipos de teste, como testes unitários, de aceitação e funcionais.
#### [Laravel Dusk](https://github.com/laravel/dusk)
O Laravel Dusk é um pacote que fornece uma API de teste e automação de navegador; ele não depende de ferramentas como JDK ou Selenium, já que utiliza de forma independente outro recurso, o ChromeDriver.
## ✅ ESTRATÉGIAS DE TESTE E CI/CD
* Entenda a proposta do projeto e, se possível, utilize como apoio algum tipo de modelo que organize as principais ideias do produto;
* Planeje com antecedência o que deverá ser testado e quais tipos de teste devem ser aplicados em cada contexto;
* Escolha as melhores ferramentas para isso! Se baseie nas tecnologias que serão usadas, nos tipos de teste e também no seu conforto;
* Sempre documente os processos de teste que você realizou! Isso te ajudará a revisá-los em outro momento, bem como ajudará outras pessoas futuramente.
## 📝 REFERÊNCIAS
* [Introdução a Testes Unitários com Jest e Vue Test Utils (Dev.to)](https://dev.to/taikio/primeiros-passos-com-vue-test-utils-3le4)
* [O que é CI/CD? (RedHat)](https://www.redhat.com/pt-br/topics/devops/what-is-ci-cd)
* [Pacote de testes automatizados para sistemas Web Laravel Dusk - DW2 (Medium)](https://medium.com/@julio.koepsel/pacote-de-testes-automatizados-para-sistemas-web-laravel-dusk-dw2-c8eb5db6f275)
* [Testes automatizados para CI/CD (JetBrains)](https://www.jetbrains.com/pt-br/teamcity/ci-cd-guide/automated-testing/)
* [Testes de software automatizados (Atlassian)](https://www.atlassian.com/br/continuous-delivery/software-testing/automated-testing)
* [Vitest: Uma evolução do Jest (Medium)](https://medium.com/@joalisonpereira/vitest-uma-evolu%C3%A7%C3%A3o-do-jest-49db62c50cc5)
* [Testing (Vue.js)](https://vuejs.org/guide/scaling-up/testing.html#testing)
* [Vue.js Testing with Cypress: A Beginner’s Handbook (Medium)](https://medium.com/simform-engineering/vue-js-testing-with-cypress-a-beginners-handbook-93c793ba74ec)
* [What is Automation Testing? Ultimate Guide & Best Practices (Katalon)](https://katalon.com/resources-center/blog/what-is-automation-testing)
---
Feito com 💚 por Andrieli Gonçalves.