Introdução a Testes no Back-end
Tags: javascript, beginners, testing, braziliandevs
Published: 2022-03-15 21:06:47

## Tabela de Conteúdos

- [Tipos de Testes](#tipos-de-testes)
- [Escrevendo Testes](#escrevendo-testes)
- [Executando Testes](#executando-testes)
- [TDD](#tdd)
- [Isolando Testes](#isolando-testes)
- [Links Úteis](#links-úteis)

---

## Tipos de Testes

### Unitário

Testes unitários trabalham no menor escopo do código, testando funções, ou classes, individualmente, variando de acordo com o paradigma.

### Integração

Testes de integração utilizam a junção de múltiplos escopos na hora de testar, ou seja, uma função que se utiliza de outras funções, essas que devem possuir seus próprios testes _(unitários)_.

### Ponta-a-Ponta

Teste de Ponta-a-Ponta _(E2E)_ verificam o fluxo da aplicação como um todo, para isso presumem que testes de menor escopo, como os Unitários e os de Integração, já tenham sido ou irão ser desenvolvidos.

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

___

## Escrevendo Testes

### Estrutura com Mocha

#### O que é?

Mocha é um framework para testes em JS, nós iremos utilizar a estrutura e a interface, disponibilizadas por ele, para a realização de nossos testes.

#### Sintaxe

A sintaxe para a estruturação dos testes é exatamente a mesma que vimos no Jest, temos um bloco `describe()` que irá descrever um ou mais testes e temos o bloco `it()` que irá definir o teste em si.

Ambas as funções, `describe()` e `it()`, recebem dois parâmetros, o primeiro é uma string que será a descrição do bloco e o segundo uma arrow function que irá definir o bloco.

``` javascript
describe('First block test', () => {
  it('First test', () => {});
  it('Second test', () => {});
});
```

_** Apesar de ter focado apenas na estrutura de tests com o Mocha nesse artigo, há outras diversas funcionalidades que esse Framework pode fazer, segue a [documentação do Mocha](https://mochajs.org)._


### Aferindo com Chai

#### O que é?

Chai é uma biblioteca para a asserção dos resultados recebidos a os resultados esperados, ou seja, criamos uma relação entre os resultados, dessa forma caso a relação seja verdadeira o teste irá passar.

#### Sintaxe

A sintaxe geral segue a mesma do Jest, temos uma função `expect()` que irá receber o resultado de nossa função, e a partir do `expect()` chamados um método de asserção para verificar se o resultado obtido é válido.

Existem diversos métodos de asserção no Chai, alguns similares aos do Jest, outros não, então a recomendação é sempre consultar a [documentação do Chai](https://www.chaijs.com/api/).

``` javascript
expect(4 + 5).equals(9);
```

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

___

## Executando Testes

### Definindo script

- Para executarmos os testes em nosso projeto, primeiro precisamos estar trabalhando em um pacote Node, então caso ainda não exista um arquivo package.json, basta executar o comando:

``` bash
npm init -y
```

- Tendo o package.json, tudo o que precisamos fazer é definir o Mocha como script de testes, para isso passamos na chave __"test"__ o valor __"mocha tests"__. E obviamente é necessário ter o Mocha instalado.

``` json
"scripts": {
  "test": "mocha tests"
},
```

- Ao definir o script como fizemos acima, iremos executar os testes contidos no diretório __tests/__, ou seja, o valor que passamos no script de teste após o mocha, refere-se ao diretório que irá conter os testes.

``` json
"scripts": {
  "test": "mocha <diretório dos testes>"
},
```

### Executando o script

Após o script ter sido definido, tudo que precisamos fazer é rodar o seguinte comando no terminal:

``` bash
npm test
```

E se quisermos rodar um teste em outro diretório, que não faça sentido alterar o script _(por qualquer motivo)_, podemos excutar os testes a partir do `npx`

``` bash
npx mocha #path até os tests
npx mocha ./my_folder/my_tests
```

Além disso também há outras flags que podemos usar ao executar o comando, elas podem ser vistas na [documentação do Mocha CLI](https://mochajs.org/#command-line-usage).

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

___

## TDD

### O que é?
É uma metodologia de desenvolvimento, na qual a pessoa desenvolvedora começa a desenvolver a aplicação a partir dos testes.

### Passos
Para usarmos essa metodologia de forma ativa podemos seguir quatro passos simples:

1. Antes de iniciarmos a escrita de código precisamos interpretar os requisitos necessários para a implementação da funcionalidade.

2. Com os requisitos em mente, começamos a escrever as estruturas descritivas dos testes com describe() e it().

3. Com as estruturas descritivas já implementadas, passamos a verdadeiramente escrever os testes, utilizando as asserções para verificar o comportamento esperado.

4. Por fim, agora que os testes já foram criados, nos resta partir para a implementação da funcionalidade pensada.

Lembrando que não há problema em realizar pequenos ajustes nos testes, afinal criamos eles para código que ainda nem existe, então um detalhe, ou outro, pode ser esquecido.

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

___

## Isolando Testes

### O que é?

O isolamento de testes é a __simulação de um comportamento esperado de uma função__, para que não seja necessário interagir com recursos externos como arquivos, APIs e Bancos de Dados.

### Por que isolar?

No Front-end trabalhamos com a manipulação do DOM, já no Back-end a maioria das operações serão de Input ou Output de dados, esses que podem ser provenientes de uma API externa, uma requisição do Front ou uma consulta no Banco de Dados.

Logo, trabalhar todas essas operações em ambiente de teste seria extremamente complexo, por exemplo: depois de testarmos a integração entre nosso Back-end e um Banco de Dados, o DB teria seus dados modificados, sendo necessário reseta-lo após cada teste.

Então para solucionar esse problema tem-se o conceito de __Test Doubles__, que nada mais são que objetos que _"fingem"_ ser outros objetos para fins de testes. Podemos ainda comparar esse conceitos às Mocks, apesar de não serem exatamente a mesma coisa, servem para o mesmo propósito.

### Como isolar?

Para isolarmos os testes iremos utilizar a biblioteca Sinon, ela oferece diversos recursos para a criação de Test Doubles. Para instalar a biblioteca basta utilizar o comando:

``` bash
npm install -D sinon
```

### Sintaxe

Podemos utilizar diversos métodos para a criação de Test Doubles com Sinon, porém o mais básico entre eles é o `.stub()`, ao chamarmos passamos dois parâmetros, o primeiro é o objeto e o segundo, caso exista, é o método a ser _"simulado"_.

Além desses parâmetros precisamos definir o valor a ser retornado quando os testes chamam o método que criamos o stub, para isso chamamos o método `returns()` logo após o método `.stub()`.

``` javascript
sinon.stub(fs, 'readFileSync').returns(/*conteúdo do arquivo*/);
```

Caso não definirmos o retorno do Test Double ela irá retornar undefined, porém há uma vantagem em _"fakear"_ sem definir retorno, pois assim a função a ser _"fakeada"_ perde a funcionalidade e a momentos que isso pode ajudar.

### Outros "isolamentos"

Como dito acima, podemos simular comportamentos através de diversos métodos do sinon, não se limitando apenas ao `.stub()`, onde cada um desses métodos possui sua especificidade, assim como um caso de uso.

Para mais detalhes sobre tais métodos consulte a [documentação do Sinon](https://sinonjs.org/releases/v13/)

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>

---

## Links Úteis

- [Mocha docs](https://mochajs.org)
- [Chai docs](https://www.chaijs.com/api/)
- [Sinon docs](https://sinonjs.org/releases/v13/)
- [DevHints - Chai Cheat Sheet](https://devhints.io/chai.html)
- [DevHints - Sinon Cheat Sheet](https://devhints.io/sinon.html)
- [DevHints - Sinon-Chai Cheat Sheet](https://devhints.io/sinon-chai.html)
- [YouTube Código Fonte TV - TDD // Dicionário do Programador](https://www.youtube.com/watch?v=bLdEypr2e-8)
- [YouTube RocketSeat - TDD na prática](https://www.youtube.com/watch?v=sg1zFpNM5Jw)

<br />

<small>[Voltar ao topo](#tabela-de-conteúdos)</small>