Teste Vazio.
Um Teste Vazio é um método de teste cujo corpo não contém nenhuma instrução executável, de modo que ele sempre passa enquanto não verifica nada.
##Sinais e sintomas
Um teste existe e é reportado como passou, mas seu corpo não tem código executável — sem configuração, sem exercício, sem asserção. Formas reveladoras:
// Corpo completamente vazio
test('calculates tax', () => {});
// Apenas um comentário de TODO / espaço reservado
it('should reject invalid input', () => {
// TODO: escrever isto quando a API estabilizar
});
// Tudo está comentado
it('parses the auth header', () => {
// const result = parse(header);
// expect(result).toEqual(expected);
});
Como identificá-lo:
- O nome do teste promete comportamento, mas o corpo é
{}, espaço em branco ou apenas comentários. - O resumo do seu executor mostra o teste como passou (verde), não pulado/pendente — é isso que o torna perigoso.
- A cobertura de código para a funcionalidade nomeada é suspeitamente zero, mesmo havendo um "teste para ela".
- Durante a revisão, o diff adiciona um caso de teste, mas nenhuma chamada
expect/assert.
Relacionado, mas distinto: um teste que tem configuração e chama o sistema sob teste, mas não faz nenhuma asserção, é o code smell Teste Sem Asserção / Teste Desconhecido. Um Teste Vazio é o caso mais extremo, em que o corpo está totalmente desprovido de instruções.
##Causas do problema
Por que acontece
- Um teste foi criado como esqueleto, servindo de espaço reservado (TDD, "escreva o nome primeiro"), e nunca foi preenchido.
- O código foi comentado para depurar uma falha ou silenciar um teste instável (flaky), depois commitado e esquecido.
- Um gerador/IDE produziu um esqueleto de stub de teste que ninguém completou.
- Um desenvolvedor quis "reservar" um nome de teste para mais tarde, mas usou um corpo vazio em vez de um marcador explícito de todo.
Por que prejudica
- Falsa confiança (a pior parte). A maioria dos executores reporta um teste vazio como passou, não como pulado. JUnit, Jest, Vitest e companhia mostrarão verde para
test('x', () => {}). A suíte parece cobrir o comportamento, mas uma regressão no código de produção nunca será detectada — possivelmente pior do que não ter teste algum, porque a marca verde engana ativamente. - Legibilidade. Um leitor vê um teste chamado
should reject invalid inpute razoavelmente supõe que esse comportamento é verificado. O nome documenta uma intenção que o corpo nunca entrega. - Manutenibilidade. Testes vazios inflam a contagem de testes e a percepção de cobertura pelo nome, escondendo lacunas reais e dificultando distinguir espaços reservados intencionais dos abandonados.
- Corrói a confiança. Quando os contribuidores percebem que "passou" não significa "verificado," o sinal de toda a suíte enfraquece.
##Tratamento
Decida se o teste já deveria existir e então faça o executor dizer a verdade.
1. Se o comportamento deve ser testado agora — preencha o corpo. Adicione arrange/act/assert para que ele realmente exercite o código:
// Antes — verde, mas não verifica nada
test('rounds half up', () => {});
// Depois — expectativa real
test('rounds half up', () => {
expect(round(2.5)).toBe(3);
});
2. Se for um espaço reservado genuíno — marque-o explicitamente como pendente para que o executor o reporte como todo/pulado (visível, não falsamente verde) em vez de deixar um corpo vazio. Um todo que cita seu ticket de rastreamento é um espaço reservado visível e honesto; um skip sem motivo nem ticket só troca este smell por um Ignored Test:
// Antes
it('should reject invalid input', () => {
// TODO
});
// Depois — aparece como um todo no relatório, nunca como "passou"
it.todo('should reject invalid input (PROJ-123)'); // Jest / Vitest — cite o ticket de rastreamento
// test.skip(...) / xit(...) só com um motivo explícito e um ticket — caso contrário, é um Ignored Test
3. Se o teste está obsoleto — exclua-o. Um teste removido é honesto; um vazio é uma mentira que custa manutenção.
4. Restaure a lógica comentada. Se o corpo estiver totalmente comentado, descomente e conserte-o ou remova o teste; nunca entregue código de teste comentado como a "implementação."
5. Adicione uma proteção. Habilite na CI uma regra de lint que exija a presença de asserções (veja os detectores) para que testes vazios/sem asserção quebrem o build em vez de passarem silenciosamente.
##Detectado por
- eslint-jest jest/expect-expect — eslint-plugin-jest: sinaliza testes sem nenhuma chamada a expect() — pega igualmente corpos vazios, só com TODO ou com o código comentado
- eslint-vitest vitest/expect-expect — eslint-plugin-vitest: a mesma verificação para Vitest — todo teste deve conter pelo menos uma chamada a expect()
- eslint no-empty-function — ESLint core: no-empty-function — só pega um callback literalmente vazio como () => {}; funções que contêm um comentário não são consideradas vazias, então corpos só com TODO ou com código comentado escapam (para eles, use expect-expect)
- sonar javascript:S2699 — SonarSource: "Testes devem incluir asserções" (Blocker; sinaliza testes sem asserção e testes vazios; há equivalentes para Java/C#/Python)
- pmd UnitTestShouldIncludeAssert — PMD 7 (Java): UnitTestShouldIncludeAssert, antes JUnitTestsShouldIncludeAssert (sinaliza testes JUnit/TestNG sem asserção, incluindo testes vazios)