📚 Material de Apoio - Testes Unitários com Java
Complemento aos estudos sobre testes unitários e qualidade de software
📖 Bibliografia Essencial
📘 Livros Fundamentais
1. “Clean Code” - Robert C. Martin
Capítulo 9: Unit Tests
- Por que importante: Estabelece padrões de qualidade para testes
- Conceitos chave: F.I.R.S.T principles (Fast, Independent, Repeatable, Self-Validating, Timely)
- Aplicação: Como escrever testes limpos e manuteníveis
2. “Test Driven Development by Example” - Kent Beck
- Por que importante: Criador da metodologia TDD
- Conceitos chave: Ciclo Red-Green-Refactor
- Aplicação: Transformar requisitos em testes first
3. “The Art of Unit Testing” - Roy Osherove
- Foco específico: Exclusivamente sobre testes unitários
- Conceitos chave: Stubs, Mocks, frameworks de teste
- Aplicação: Mais técnico e detalhado que os anteriores
📄 Artigos Online Recomendados
Martin Fowler - “UnitTest”
🔗 https://martinfowler.com/bliki/UnitTest.html
- Definição autorativa de teste unitário
- Diferenças entre unit/integration/system tests
Google Testing Blog
🔗 https://testing.googleblog.com/
- Práticas de uma das maiores empresas de software
- Casos reais e soluções para problemas complexos
🎥 Recursos Audiovisuais
📺 Vídeos Introdutórios (YouTube)
“JUnit 5 Tutorial for Beginners” (inglês)
- Duração: 45 minutos
- Nível: Iniciante
- Conteúdo: Setup básico até testes avançados
- Vantagem: Demonstração visual passo a passo
”Test-Driven Development - TutorialsPoint” (português)
- Duração: 30 minutos
- Nível: Intermediário
- Conteúdo: Aplicação prática de TDD em Java
- Vantagem: Em português com exemplos locais
🎓 Cursos Online Estruturados
”Java Testing with JUnit” - Udemy
- Duração: 8 horas
- Nível: Iniciante a Intermediário
- Inclui: Projetos práticos e certificado
- Preço: Frequentemente em promoção
”Test-Driven Development in Java” - Pluralsight
- Duração: 6 horas
- Nível: Intermediário a Avançado
- Inclui: TDD, Mockito, advanced patterns
- Vantagem: Qualidade profissional reconhecida
🔧 Ferramentas e Frameworks
⚙️ Essenciais (já abordados)
JUnit 5
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.2</version>
</dependency>- Vantagens: Padrão da indústria, bem documentado
- Usar quando: Sempre - é a base
Maven Surefire Plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>- Função: Executar testes no build
- Vantagem: Integração com CI/CD
🚀 Ferramentas Avançadas (próximos passos)
Mockito - Mocking Framework
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.1.1</version>
</dependency>- Função: Simular dependências externas
- Usar quando: Testar classes que dependem de BD, APIs, etc.
- Exemplo:
@Mock
private UserService userService;
@Test
void deveProcessarUsuarioValido() {
when(userService.findById(1)).thenReturn(new User("João"));
// teste continua...
}AssertJ - Fluent Assertions
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.24.2</version>
</dependency>- Vantagem: Assertions mais legíveis
- Exemplo:
// Ao invés de:
assertEquals("João", user.getName());
assertTrue(user.isActive());
// Use:
assertThat(user)
.hasFieldOrPropertyWithValue("name", "João")
.matches(User::isActive);Testcontainers
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.17.6</version>
</dependency>- Função: Testes de integração com banco real
- Usar quando: Testar queries complexas, procedures
📊 Test Coverage Tools
JaCoCo
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
</plugin>- Função: Medir cobertura de código
- Meta: Não menos que 80% em projetos profissionais
- Comando:
mvn jacoco:report
🎯 Padrões e Best Practices
✅ Nomenclatura de Testes
Padrão Recomendado:
// MethodName_StateUnderTest_ExpectedBehavior
@Test
void withdraw_InvalidAccount_ThrowsException() {}
// Should_ExpectedBehavior_When_StateUnderTest
@Test
void should_ThrowException_When_WithdrawFromInvalidAccount() {}
// Given_Preconditions_When_StateUnderTest_Then_ExpectedBehavior
@Test
void given_InsufficientBalance_When_Withdraw_Then_ThrowsException() {}Em português (para ambiente acadêmico):
@Test
void deveLancarExcecaoAoSacarDeContaInvalida() {}
@Test
void deveRetornarSaldoZeroParaContaNova() {}🏗️ Organização de Código
Estrutura de Pastas Recomendada:
src/
├── main/java/
│ └── br/com/empresa/
│ ├── model/
│ ├── service/
│ └── util/
└── test/java/
└── br/com/empresa/
├── model/ ← Testes unitários
├── service/ ← Testes unitários
├── util/ ← Testes unitários
└── integration/ ← Testes integração
Setup Cleanups Pattern:
public class AccountServiceTest {
private AccountService service;
private Account testAccount;
@BeforeEach
void setUp() {
service = new AccountService();
testAccount = new Account("123", BigDecimal.ZERO);
}
@AfterEach
void tearDown() {
// Limpar recursos se necessário
testAccount = null;
}
@Test
void shouldIncreasBalanceOnDeposit() {
// Arrange já feito no setUp
BigDecimal amount = new BigDecimal("100.00");
// Act
service.deposit(testAccount, amount);
// Assert
assertThat(testAccount.getBalance()).isEqualTo(amount);
}
}⚡ Troubleshooting Avançado
🔧 Problemas de Performance
Testes muito lentos
// ❌ Problema: Setup pesado em cada teste
@BeforeEach
void setUp() {
database = new ExpensiveDatabase(); // ← Lento!
}
// ✅ Solução: Setup compartilhado quando possível
@BeforeAll
static void setUpClass() {
database = new ExpensiveDatabase();
}Memory leaks em testes
// ❌ Problema: Recursos não liberados
@Test
void testWithFileHandle() {
FileInputStream file = new FileInputStream("test.txt");
// teste sem fechar arquivo
}
// ✅ Solução: Try-with-resources
@Test
void testWithFileHandle() {
try (FileInputStream file = new FileInputStream("test.txt")) {
// teste automaticamente fecha arquivo
}
}🐛 Debugging de Testes
Falhas intermitentes (flaky tests)
// ❌ Problema: Dependência de timing
@Test
void testAsyncOperation() {
service.startAsyncTask();
Thread.sleep(100); // ← Perigoso!
assertTrue(service.isCompleted());
}
// ✅ Solução: Aguardar condição específica
@Test
void testAsyncOperation() {
service.startAsyncTask();
await().atMost(5, SECONDS)
.until(() -> service.isCompleted());
}Uso de @Disabled temporariamente
@Test
@Disabled("TODO: Fix after refactoring authentication")
void testUserLogin() {
// Teste temporariamente desabilitado
}📈 Métricas e Qualidade
📊 KPIs de Qualidade em Testes
Cobertura de Código (Code Coverage)
- Meta mínima: 80%
- Meta ideal: 90%+
- Atenção: 100% nem sempre é realista ou necessário
Mutação Testing
- Ferramenta: PITest para Java
- Conceito: “Matar” mutações no código
- Meta: 85%+ mutation score
Test Pyramid Health
Sistema (5%) ← Poucos, caros, lentos
Integração (15%) ← Alguns, médios
Unitário (80%) ← Muitos, rápidos, baratos
⏱️ Performance Benchmarks
Tempo de Execução Aceitável:
- Testes unitários: < 10ms por teste
- Suite completa: < 5 minutos
- Build + testes: < 10 minutos
Paralelização:
<!-- Maven Surefire parallel execution -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<parallel>methods</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>🎓 Certificações e Cursos
🏅 Certificações Profissionais
ISTQB (International Software Testing Qualifications Board)
- Foundation Level: Base teórica de testes
- Agile Testing: Foco em metodologias ágeis
- Test Automation: Especialização em automação
Oracle Certified Professional Java
- Inclui seção sobre debugging e testing
- Reconhecido no mercado brasileiro
🎒 Cursos Presenciais/Online
Alura - Trilha Java e Testes
- Curso estruturado em português
- Projetos práticos
- Certificado reconhecido
Caelum/K21 - Práticas de Desenvolvimento
- Foco em TDD e qualidade
- Instrutor experiente
- Networking com profissionais
🔗 Links de Referência
📚 Documentação Official
💻 Código de Exemplo
🏢 Práticas da Indústria
🚀 Roadmap de Evolução
📅 Próximos 30 dias
- ✅ Fixar conceitos desta aula com exercícios
- 📖 Ler capítulo sobre testes do “Clean Code”
- 💻 Implementar TDD em projeto pessoal
- 🛠️ Experimentar AssertJ em lugar de assertions nativas
📅 Próximos 90 dias
- 🧪 Aprender Mockito para testar com dependências
- 📊 Configurar cobertura de código com JaCoCo
- 🔄 Participar de projeto open source com boa cobertura
- 🎯 Aplicar em projeto real no trabalho/estágio
📅 Próximos 6 meses
- 📜 Estudar para certificação ISTQB Foundation
- 🏗️ Implementar testes de integração com Testcontainers
- ⚙️ Configurar CI/CD com execução automática de testes
- 👥 Compartilhar conhecimento mentorando outros
💬 Fóruns e Comunidades
🌐 Brasil
- Java Brasil (Telegram): Grupo ativo com profissionais
- DevBrasil (Discord): Canais específicos para testing
- Stack Overflow PT: Para dúvidas específicas
🌍 Internacional
- r/java (Reddit): Discussões e tendências
- JUnit User Guide Issues: Para reportar problemas
- Testing Library Community: Slack/Discord
Continue aprendendo e praticando! 📈✨
O investimento em qualidade de código através de testes é um dos melhores diferenciais que um desenvolvedor pode ter no mercado profissional.