O documento discute os benefícios do TDD (Test-Driven Development), incluindo aumentar a confiabilidade do código através da escrita de testes antes do código, contribuir para o aprimoramento do design do código, e aumentar a expectativa de vida do programador. As ferramentas comumente usadas incluem JUnit para testes e Mockito para simular objetos.
1. Por quê você deveria utilizar o TDD?
Prática com Testes Unitários
(JUnit e Mockito)
2. O que o TDD não é?
● Teste unitário
● Biblioteca de Testes
● Feitiçaria
3. Mas afinal, o que é TDD (Test-Driven Development)?
● Técnica de desenvolvimento "descoberta" por Kent Beck em 2003
● Escrita de testes antes do código
● Ciclos curtos e contínuos (Red-Green-Refactor)
4. Mas afinal, o que é TDD (Test-Driven Development)?
● Aumenta a confiabilidade do código
● Contribui para o aprimoramento do Code Design
● Aumenta a expectativa de vida do programador
5. Ferramentas utilizadas
● Intellij Idea CE - IDE
● JUnit - Ferramenta para escrita/execução de testes
○ Baseada no xUnit, assim como PHPUnit, xUnit.NET, etc.
● Mockito - Ferramenta para "simular" objetos configuráveis, sem
depender da implementação real. Falaremos disso mais adiante :)
6. Testar antes + Red - Green - Refactor
1. Escreva um teste que falhe
2. Faça-o rodar com sucesso
3. Refatore-o / Elimine redundâncias
8. Triangulação!
● Analogia da triangulação de radares
● Dois ou mais radares apontam para o
mesmo alvo
● As distâncias entre os radares e o alvo
podem resultar na distância real do alvo.
9. Por quê TDD aumenta a confiabilidade do código?
● Código sem testes = Queijo suíço (+ queijo é - queijo)
● Quanto mais testes válidos*, menos "gaps"
● Menor índice de bugs (e maior TMEF)
● Código ruim de testar é um Code Smell**
* Testes mal escritos e/ou inválidos podem garantir que o bug existe, e permanecerá existindo
** Se o código cheira mal, está estragando/estragado (software rot) - Kent Beck, Martin Fowler, Ward
Cunningham, Robert C. Martin, etc.
10. ● Encontrou um bug? Red-Green-Refactor!
Por quê TDD aumenta a confiabilidade do código?
1. Escreva um teste que falhe (Simulando o bug encontrado)
2. Faça-o passar (Corrigindo o bug - n ciclos)
3. Refatore!
Rode a suíte de testes, se todos os testes passarem então é provável
que você tenha corrigido o bug :)
11. ● Aprimora o Code Design do seu Software. Exemplo? SOLID
Por quê TDD aumenta a confiabilidade do código?
Single Responsibility - A classe ou módulo só pode ter um motivo para
mudar
Exemplo: Uma alteração de
comportamento na classe Engine não
deverá obrigar mudanças nas
classes Order e Car (efeito cascata)
12. ● Aprimora o Code Design do seu Software. Exemplo? SOLID
Por quê TDD aumenta a confiabilidade do código?
Open-Closed - A classe ou módulo deverá ser aberta para extensão, mas
fechada para modificações
Exemplo: Adicionar uma propriedade
(attributo) à class Product não deverá
obrigar mudanças no método
Order.addProduct(Product p)
13. ● Aprimora o Code Design do seu Software. Exemplo? SOLID
Por quê TDD aumenta a confiabilidade do código?
Liskov Substitution - Se uma interface B estende uma interface A, então
uma implementação de B poderá ser representada por A ou B
14. ● Aprimora o Code Design do seu Software. Exemplo? SOLID
Por quê TDD aumenta a confiabilidade do código?
Interface Segregation - Segregar (Dividir, especializar) interfaces
Exemplo: O consumidor de
um módulo não poderá
ser obrigado a depender
de métodos que não
utiliza.
15. ● Aprimora o Code Design do seu Software. Exemplo? SOLID
Por quê TDD aumenta a confiabilidade do código?
Dependency Inversion - Prefira Abstrações (Interfaces) à Concreções
(Classes).
16. - "Legal esse negócio de TDD que você
comentou. Mas uma função de soma não é
simples demais? E pra fazer algo mais
complexo?"
17. ● Entender o que precisa ser entregue
● Adicionar as primeiras tarefas "que vierem à cabeça"
● Eleger a "próxima" a ser realizada (A que necessitar de menor esforço)
Lista de Tarefas (TODO List)
18. ● Riscar as finalizadas e adicionar as que surgirem
● Acabou o expediente? Vá para casa. Amanhã você pega a lista e
continua.
● Quando as tarefas acabarem, e você não conseguir pensar em mais
nenhuma, será que está pronto*?
Lista de Tarefas (TODO List)
20. ● Testes Unitários deverão ser executados isoladamente
○ A ordem de execução não poderá alterar os resultados
○ Não poderão depender de fatores externos (Implementações
(Concreções), Arquivos, Bancos de Dados, WebServices, etc.)
● Podemos simular interações utilizando Mock, Stub e/ou Fake
Instâncias "Faz-de-conta"
21. ● "Simulação" de instância de objeto
● Um mock pode ser criado a partir de uma interface (Não depende da
implementação)
● É configurado conforme o objetivo do caso de teste
Mock
22. ● "Simulação" de interações controladas a um objeto, e verificação de
interações após a execução.
● Mock = teste de comportamento, e verificação de retornos (asserts)
● Stub = teste de interações, e verificação das mesmas (Quantas
execuções, qual o valor fornecido)
Stub
23. ● Objeto que simula um Data Store (ex: Banco de Dados), utilizando In-
Memory Databases (h2, derby, etc.), ou até mesmo Collections.
○ Testar a lógica sem utilizar as implementações das dependências
○ Implementação leve (lightweight) para execuções de testes mais
rápidas.
Fake