Para projetos JavaScript críticos, a implementação de testes unitários eficazes é crucial. O Mocha é um framework de teste rico em funcionalidades que suporta tanto ambientes Node.js quanto navegadores. Ele lida bem com código assíncrono, essencial para JavaScript, executando testes de forma serial e gerando relatórios detalhados.
Instalação do Mocha
Para instalar globalmente, execute:
npm install mocha -g
Exemplo Básico de Teste
Crie um diretório test e adicione um arquivo specimen.js:
const { expect } = require('chai');
describe('Coleção', () => {
describe('#buscar()', () => {
it('deve retornar -1 para elementos ausentes', () => {
const itens = [10, 20, 30];
expect(itens.indexOf(50)).to.equal(-1);
expect(itens.indexOf(100)).to.equal(-1);
});
});
});
Execute mocha no terminal para ver os resultados. A estrutura describe agrupa testes, enquanto it define casos individuais com asserções.
Módulos de Asserção Suportados
O Mocha funciona com qualquer módulo que lance erros, como chai, should.js ou expect.js. Cada um oferece sintaxes diferentes para validações.
Testes Síncronos e Assíncronos
Para código síncrono, o teste termina quando a função retorna. Para assíncrono, use callbacks ou promises:
// Teste assíncrono com callback
describe('Usuário', () => {
describe('#salvar()', () => {
it('deve salvar sem erros', (done) => {
const user = new Usuario('Ana');
user.save((err) => {
if (err) throw err;
done();
});
});
});
});
Para promises, retorne a promise no teste:
beforeEach(() => {
return banco.limpar().then(() => banco.gravar([dado1, dado2]));
});
describe('#consultar()', () => {
it('deve retornar registros correspondentes', () => {
return banco.consultar({ tipo: 'Registro' }).should.eventually.have.length(2);
});
});
Evitando Funções Seta
Funções seta não permitem acesso ao contexto do Mocha (como this.timeout()). Use funções convencionais para acessar métodos de teste.
Funções de Gancho
Use before(), after(), beforeEach(), afterEach() para preparar e limpar ambientes:
describe('Testes', () => {
before(() => { /* configuração única */ });
beforeEach(() => { /* setup por teste */ });
// casos de teste
afterEach(() => { /* limpeza por teste */ });
after(() => { /* teardown único */ });
});
Ganchos assíncronos são suportados com callbacks ou promises. Ganchos globais definidos fora de describe afetam todos os testes.
Recursos Avançados
Casos de Teste Pendentes
Defina testes sem implementação:
it('deve fazer algo no futuro');
Filtrando Testes
Use .only() para executar apenas um conjunto ou caso específico, ou .skip() para pular. this.skip() pode ser chamado durante a execução.
Reexecução de Testes
Especifique tentativas para testes que falham, útil para testes end-to-end:
describe('Retentativas', function() {
this.retries(3);
it('deve passar após tentativas', () => { /* lógica */ });
});
Geração Dinâmica de Testes
Use loops para criar testes baseados em dados:
const testes = [
{ args: [5, 3], expected: 8 },
{ args: [-1, 4], expected: 3 }
];
testes.forEach(({ args, expected }) => {
it(`soma ${args} corretamente`, () => {
const soma = (a, b) => a + b;
expect(soma(...args)).to.equal(expected);
});
});
Controle de Tempo
Defina tempos de espera e limites com this.slow() e this.timeout(). Use this.timeout(0) para desativar timeouts.
Comparação de Diferenças
O Mocha exibe diffs quando asserções falham, mostrando valores esperados e obtidos se o módulo de asserção suportra.
Comendos e Parâmetros
Inicialize testes no navegador com mocha init diretorio. Parâmetros comuns incluem:
--reporter: Define o formato do relatório (spec, dot, json, etc.).--timeout: Configura o tempo limite para testes.--grep: Filtra testes por padrão.--ui: Seleciona a interface de teste (bdd, tdd, exports).
Um arquivo mocha.opts pode armazenar configurações padrão.
Interfaces de Teste
O Mocha oferece múltiplas interfaces:
- BDD: Padrão, com
describe,it,context. - TDD: Usa
suite,test,setup. - Exports: Define testes via exportações de módulos.
- QUnit: Combina estilos BDD e TDD.
Relatórios de Teste
Divesros visualizadores estão disponíveis, como spec (padrão), dot, nyan, json, html. Use --reporter para selecionar.
Execução no Navegador
Inclua mocha.js e mocha.css no HTML. Configure com mocha.setup('bdd') e execute com mocha.run(). Use parâmetros de URL como ?grep=padrão para filtrar.