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.
Top comments (0)