Série: Fundamentos da Engenharia de Software | Parte 15 de 19 > Ministrada na Universidade Potiguar (UnP) em 2010
Nesta aula, expandimos nosso estudo sobre TDD com foco nos testes unitários, utilizando o JUnit para mostrar como a validação estruturada transforma lógica vaga em comportamento previsível. A proposta não era apenas testar, mas construir laços de feedback, melhorar o design e reduzir surpresas durante o desenvolvimento.
Quis que a turma entendesse: testar cedo não é apenas programar com defesa. É guiar o desenvolvimento pela intenção.
Antes dos Frameworks: Testes Crus e Seus Limites
Começamos voltando no tempo, para antes do JUnit. Demonstrei como testar um método que calcula raízes quadradas com Java puro. Utilizamos a classe Calculadora
:
public final class Calculadora {
public static int qualARaiz(int x) {
int guess = 1;
while (guess * guess < x) {
guess++;
}
return guess;
}
}
E testamos manualmente:
public static void main(String[] args) {
System.out.println(Calculadora.qualARaiz(0));
System.out.println(Calculadora.qualARaiz(9));
System.out.println(Calculadora.qualARaiz(100));
}
Qual o problema? Não há verificação automática de falhas. É frágil, manual e não escalável.
Entra o JUnit: Nomenclatura, Fixtures e Automação
Apresentamos o JUnit—framework criado por Kent Beck. Definimos os termos-chave:
- Fixture: dados preparados para os testes
- Test Case: método de validação
- Test Suite: conjunto de testes
- Test Runner: executa e reporta os testes
A turma escreveu seu primeiro teste anotado:
@Test
public void testCalculaRaiz() {
assertEquals(3, Calculadora.qualARaiz(9));
assertEquals(10, Calculadora.qualARaiz(100));
}
Discutimos o poder de bons nomes e estrutura clara. Testes bem escritos se tornam documentação executável.
Exemplos com Aritmética e Condições
Expandimos com nova lógica de negócio:
public class Aritmetica {
public static int soma(int i, int j) {
return i + j;
}
public static boolean isPositivo(int numero) {
return numero > 0;
}
}
E os testes:
@Test
public void testSoma() {
assertEquals(4, Aritmetica.soma(2,2));
assertEquals(-15, Aritmetica.soma(-10, -5));
}
@Test
public void testIsPositivo() {
assertTrue(Aritmetica.isPositivo(5));
assertFalse(Aritmetica.isPositivo(-10));
}
Aqui, os alunos aprenderam que métodos com responsabilidade única facilitam a validação. E que booleans ajudam a evidenciar falhas rapidamente.
Modelando Comportamento com Contador
Na segunda parte, introduzimos um exemplo mais prático: um Contador
para filas.
public class Contador {
private int count = 0;
public int increment() {
return ++count;
}
public int decrement() {
return --count;
}
}
E os testes:
@Before
public void setUp() {
counter = new Contador();
}
@Test
public void testIncrementa() {
assertEquals(1, counter.increment());
assertEquals(2, counter.increment());
}
@Test
public void testDecrementa() {
assertEquals(-1, counter.decrement());
}
Os alunos aplicaram o uso do @Before
para isolar a criação do objeto. Aprenderam que testes independentes aumentam a confiabilidade.
Atividade e Aprendizado
Finalizamos com um desafio: implementar e testar uma classe que valida elegibilidade para votar. Cada equipe teve que definir:
- O que caracteriza um usuário válido
- Quais regras se aplicam
- Como testar bordas e restrições
Na revisão entre times, entenderam a diferença entre testar lógica e testar comportamento. E perceberam como a estrutura de testes influencia na manutenção e colaboração.
Facilitadores podem usar esse modelo em treinamentos, mentorias ou programas de integração. Basta escolher uma classe simples, definir os comportamentos e testá-los com clareza.
Postado como parte do diário do curso de Engenharia de Software. Hoje aprendemos que testes unitários com JUnit não são apenas sobre capturar bugs—são sobre construir sistemas que comunicam sua intenção claramente e evoluem com segurança.
Navegação da Série
- Introdução: Parte 1 - Por que Engenharia de Software?
- Anterior: Parte 14 - Desenvolvimento Orientado a Testes
- Próxima: Parte 16 - TDD Avançado: Pensando com Testes
- Atual: Parte 15 - Testes Unitários com JUnit
- Série completa: Por que Engenharia de Software? | Domando a Complexidade | Modelo Cascata | Modelos Evolutivos | Mentalidade Ágil | Produtividade Scrum | Ciclo Scrum | XP Qualidade & Coragem | XP Princípios & Práticas | XP na Prática | Domain-Driven Design | Requisitos & Testes | Testando Software | Desenvolvimento Orientado a Testes | Testes Unitários com JUnit | TDD Avançado: Pensando com Testes