Testabilidade em Javascript 🧪
Tags: javascript, testing, testabilidade, software
Published: 2024-04-06 19:08:24

Testabilidade é sobre o quão **fácil** é escrever testes para um pedaço do seu código. Para que um código seja fácil de testar, ele precisa ser bem **organizado** e seguir bons princípios de **design**, como ter funções com responsabilidades claras e separadas, **evitar** dependências complicadas entre partes do código e outras boas práticas de programação.

---

## Exemplo: Cálculo de IMC 📏👤 

Num cenário inicial complicado para testes, poderia existir um cáculo de IMC, e  todo o cálculo e interação com o usuário, estar tudo **misturado** numa **única** função ou módulo. Isso faria com que testar o cálculo do IMC fosse **difícil**, pois você teria que simular toda a interação do usuário.

Para **melhorar** a testabilidade, o melhor seria **separar** a lógica do cálculo do IMC em um módulo separado, deixando a interação com o usuário para outra parte do código. Isso torna muito mais **simples** escrever testes unitários para a lógica do IMC, pois você pode testá-la diretamente sem se preocupar com as partes de interação do usuário.

```
// IMCModel.js
class IMCModel {
  calculaIMC(peso, altura) {
    return peso / (altura * altura);
  }
}

module.exports = IMCModel;
```

E então, em outra parte do código, **lidar** com a interação do usuário:

```
// IMCController.js
const IMCModel = require('./IMCModel');
const model = new IMCModel();

function calculaEExibeIMC(peso, altura) {
  const imc = model.calculaIMC(peso, altura);
  console.log(`Índice de Massa Corporal (IMC): ${imc}`);
}

calculaEExibeIMC(70, 1.75);

```

Nesse exemplo, `IMCModel` contém apenas a lógica para calcular o IMC, tornando-a fácil de testar de forma isolada. Não é necessário se preocupar com detalhes de como o peso e a altura são obtidos ou como o resultado é exibido. Essa separação de responsabilidades melhora a testabilidade do código.

Essa abordagem mostra como o **design** do código influencia diretamente na facilidade de testá-lo. **Separar** a lógica de domínio da apresentação não só torna seu código mais limpo e organizado, mas também muito mais fácil de testar.

---

## Exemplo: Chamada Assíncrona ⏳🔄

Trabalhar com código assíncrono é algo bem comum, especialmente quando se trata de operações como chamadas de rede, leituras de arquivo, ou qualquer tarefa que leve tempo para ser concluída. Isso torna o teste dessas funções um pouco mais desafiador, mas não impossível.
Vamos começar com uma classe `MyMath` que contém uma função assíncrona para calcular PI e uma versão síncrona dessa mesma função para facilitar os testes:

```
class MyMath {
  // Função síncrona que calcula PI.
  syncPI(prec) {
    let pi = 0;
    for (let k = 0; k < prec; k++) {
      pi += Math.pow(-1, k) / (2 * k + 1);
    }
    return pi * 4;
  }

  // Função assíncrona que utiliza a versão síncrona para calcular PI.
  async asyncPI(prec) {
    return new Promise((resolve) => {
      setTimeout(() => {
        const pi = this.syncPI(prec);
        resolve(pi);
      }, 1000); // Simula um cálculo que leva tempo com setTimeout.
    });
  }
}

module.exports = MyMath;

```
Testando o Código Assíncrono em JavaScript: 

```
const MyMath = require('./MyMath');
const myMath = new MyMath();

describe('MyMath', () => {
  test('asyncPI returns the correct PI value', async () => {
    const prec = 10; // Define a precisão como exemplo.
    const piValue = await myMath.asyncPI(prec);
    expect(piValue).toBe(3.0418396189294032);
  });
});

```

Neste teste, você usa `async/await` para esperar a promessa retornada por asyncPI ser resolvida. Jest espera automaticamente pela resolução da promessa quando você declara a função de teste com async.

Isso mostra uma abordagem prática para **melhorar** a testabilidade de código assíncrono: **separar** a lógica complexa em funções síncronas que podem ser testadas independentemente e, em seguida, usar essas funções em operações assíncronas. Esse método não apenas torna seu código **mais testável**, mas também o mantém organizado e fácil de entender.

---

A maior parte desse conteúdo veio do livro "Engenharia de Software Moderna", escrito por Marco Tulio Valente. Esse livro é um tesouro cheio de dicas sobre como criar testes do jeito certo, usando o que tem de mais novo e eficiente no mundo da programação. Entretanto, a única diferença, é que o livro é em Java e aqui eu adaptei para utilizar Javascript.

---