Testes

Teste é um código que verifica se outro código funciona. Quando o teste passa, você sabe que a função continua fazendo o que deveria. Quando uma mudança quebra alguma coisa em outro canto, o teste avisa na hora — não na mão do usuário.

0:00 / 0:00
O que é um teste +

Um teste é um pedaço de código que chama outro código e verifica o resultado. Se o resultado for o esperado, passa. Se não for, falha — e o teste te diz o que esperava e o que veio.

Exemplo simples: uma função soma(a, b). O teste chama soma(2, 3) e verifica se voltou 5.

// código que vai ser testado
public int soma(int a, int b) {
    return a + b;
}

// código de teste
@Test
public void somaDeveRetornarSomaDosDois() {
    int resultado = soma(2, 3);
    assertEquals(5, resultado);
}

Um teste é só isso: chamar e comparar.

Por que evita quebra — regressão +

Regressão é quando uma mudança nova quebra algo que já funcionava. Você arruma o bug em A — e sem perceber quebra B, que dependia de A do jeito antigo.

Sem teste, você descobre quando o usuário reclama (no pior momento). Com teste, ele falha no segundo em que você salva — porque toda vez que o código muda, todos os testes rodam.

Sem testesCom testes
Quebrou e ninguém viuQuebrou e o teste apita
Bug aparece em produçãoBug aparece antes do commit
Refatorar dá medoRefatorar é seguro

O ganho não é só "achar bugs". É mexer no código sem medo — porque se você quebrar algo, vai saber.

TDD — Red, Green, Refactor +

TDD é Test-Driven Development — desenvolvimento guiado por testes. A ordem é invertida: primeiro o teste, depois o código que faz o teste passar.

O ciclo tem 3 passos, repetidos uma feature de cada vez:

PassoO que você fazEstado
1. RedEscreve o teste do código que ainda não existe. Roda. Ele falha.🔴 vermelho
2. GreenEscreve o código mínimo que faz o teste passar. Roda. Passa.🟢 verde
3. RefactorLimpa o código (nomes, duplicação) sem quebrar o teste.🟢 verde

Depois do Refactor, volta pro Red da próxima feature. Ciclo de novo.

TDD — por que escrever o teste antes +

À primeira vista parece estranho: como testar algo que não existe? Mas é justamente esse o ponto.

Escrever o teste primeiro te força a decidir o comportamento antes da implementação:

  • Como a função vai ser chamada? O teste responde isso na primeira linha.
  • O que ela deve devolver? O teste já cobra o resultado esperado.
  • Quais são os casos de erro? Cada caso vira um teste.

Você desenha a interface (como o código vai ser usado) antes de pensar em como resolver. E só implementa o que o teste pediu — sem código sobrando, sem feature inventada.

Sem TDDCom TDD
Implementa primeiro, testa depois (ou nunca)Testa primeiro, implementa depois
Tende a sobrar código "pra todo caso"Só existe o que o teste pediu
Interface descoberta no meio do caminhoInterface decidida antes
TDD na prática — exemplo soma(a, b) +

Vamos rodar o ciclo Red → Green → Refactor numa função soma(a, b). Ela ainda não existe.

1. Red — escrever o teste primeiro

O código abaixo nem compila ainda — a função soma não existe. É proposital: o teste descreve o que deveria existir.

@Test
public void somaDeveRetornarSomaDosDois() {
    int resultado = soma(2, 3);
    assertEquals(5, resultado);
}

Roda → falha (não compila ou o assert quebra). 🔴

2. Green — implementação mínima

Agora escreve só o necessário pra esse teste passar. Nada além disso.

public int soma(int a, int b) {
    return a + b;
}

Roda → passa. 🟢

3. Refactor — limpar mantendo verde

Olha o código: nome bom, sem duplicação, sem lógica complicada. Não tem nada a melhorar nesse ciclo. Pula pro próximo Red.

Próximo ciclo: e se um for negativo?

Você lembra de um caso novo: soma(-1, 1). Escreve o teste, roda. Já passa? Ótimo, segue. Falha? Volta pro Green.

@Test
public void somaDeveLidarComNegativos() {
    assertEquals(0, soma(-1, 1));
}

É assim que o código cresce: um caso de cada vez, sempre com teste do lado.