Desenvolvimento Dirigido a Testes
Prof. Alysson Filgueira Milanez
alysson.milanez@academico.ifpb.edu.br
Testes de Software
TDD
2
TDD
Test-Driven Development
Essência: escreva testes e codifique um pouco; isto em etapas alternativas e incrementais
3
TDD
Um caso de teste é escrito primeiro, e, na ausência do código correspondente, o caso de teste falha ao ser executado
4
TDD
De imediato, apenas o código suficiente para o teste passar é escrito
5
TDD
À medida que o código cresce, refatoramento pode ser realizado, mas os testes originais devem continuar passando - do contrário não se trata de uma atividade de refatoramento
6
TDD
TDD se tornou muito popular na comunidade de desenvolvimento ágil
7
TDD
TDD se baseia em pequenos ciclos de repetição:
- criamos um teste para cada nova funcionalidade;
- o teste falha, daí implementamos a funcionalidade para o teste passar;
- aprimoramos o código (refatoramos)
8
TDD
Um dos objetivos da prática de TDD é criar código limpo e que funciona
9
TDD
Aumenta a cobertura do código - toda nova funcionalidade tem ao menos um caso de teste
Pode levar a aumentos na qualidade do produto de software
10
TDD
TDD proporciona um senso de evolução passo a passo em direção à conclusão do seu projeto
11
Ciclo de Desenvolvimento
12
TDD
Toma por base o ciclo: red, green, refactoring
13
TDD
Toma por base o ciclo: red, green, refactoring
Mantra do TDD
14
TDD
Auxilia a isolar faltas: se um novo caso de teste falha, a falta só pode estar relacionada ao código recentemente adicionado
Todos os demais testes continuam a passar
15
TDD
Isso não é tão óbvio para faltas mais profundas, reveladas via teste de fluxo de dados
16
TDD
Novo teste: escrevemos o código que irá testar a nova função (ainda não implementada)
É necessário especificar bem qual a entrada e a saída do código a ser testado
Se a especificação for ruim, deu ruim
17
TDD
O fato de termos um teste primeiro que o código garante que daremos passos simples para a codificação da funcionalidade: implementação simples para que o teste passe
18
TDD
Como ainda não existe o código, o teste falha (red)
19
TDD
Daí criamos a funcionalidade - escrevemos o código
Faremos isso da forma mais simples possível
20
TDD
O código que acabamos de escrever passou no teste e não quebrou outros testes (green)
Garantir que não houve regressão de funcionalidade
21
TDD
Código limpo, simples e funcional
Esta é a ideia
22
TDD
Agora é hora de refatorar: O TDD nos obriga a escrever códigos menos acoplados e mais coesos para que se tornem mais “testáveis”
refactoring
23
TDD
É neste momento que podemos deixar o nosso código simples e claro e o melhor de tudo: Funcional!
24
TDD
Como conseguimos um código simples? Fazendo um Teste passar
25
TDD
Como conseguimos um código claro? Refatorando o código após ele passar
26
TDD
Como conseguimos um código seguro? Com Testes
27
TDD
SRP - Single Responsibility Principle
Este princípio nos diz que devemos ter somente um motivo para modificar uma classe
Ou seja, ele fala sobre termos uma classe com somente uma responsabilidade
28
TDD
Usando TDD a suíte de testes pode ser usada como documentação das funcionalidades do sistema
29
Por que usar?
30
TDD
Feedback rápido sobre a nova funcionalidade e sobre as outras funcionalidades existentes no sistema
31
TDD
Código mais limpo, já que escrevemos códigos simples para o teste passar
32
TDD
Segurança no Refactoring pois podemos ver o que estamos ou não afetando
33
TDD
Segurança na correção de bugs
34
TDD
Maior produtividade já que o desenvolvedor encontra menos bugs e não desperdiça tempo com depuradores
35
TDD
Código da aplicação mais flexível, já que para escrever testes temos que separar em pequenos "pedaços" o nosso código, para que sejam testáveis, ou seja, nosso código estará menos acoplado
36
Exemplos de uso
37
TDD
Usaremos Java + Eclipse + JUnit
38
TDD
Criar uma Calculadora que calcula as 4 operações básicas: Adição, Subtração, Multiplicação e Divisão
39
TDD
Passos:
- Crie um projeto no Eclipse com o nome TDD
- Crie um pacote tdd.calculadora.teste
40
TDD
Criada a estrutura básica, vamos criar a nossa primeira classe
CalculadoraTeste
41
TDD
Vamos fazer um Teste em algo que ainda não temos implementado
42
TDD
Nossa calculadora terá as 4 operações básicas
Que tal começarmos com uma soma: como testar uma soma?
43
TDD
Dados dois valores, o resultado deveria ser a soma deles
Assim criamos o método
44
TDD
45
TDD
Vamos agora inserir duas variáveis e usar o método "assertEquals" do próprio JUnit
46
TDD
Eis o código
47
TDD
Ao executar…
Red bar
48
TDD
Isto já era esperado:
Test -> Red -> Green -> Refactor
49
TDD
Podemos analisar o trace para entender o erro
50
TDD
O JUnit indica que esperava o valor 3 porém foi encontrado o valor 0
E agora o nosso objetivo é fazer o Teste passar
Colocamos agora a classe responsável pela implementação da funcionalidade
51
TDD
52
TDD
Como assim jóvis???
53
TDD
Como assim jóvis???
É isso mesmo: usamos a classe antes de criá-la
54
TDD
Agora criamos a classe e o método
55
TDD
Então implementamos o método
56
TDD
Daí vemos a tão desejada green bar
57
TDD
A última etapa seria a refatoração, mas o nosso sistema ainda é simples demais
58
TDD
Seguindo os mesmos passos anteriores, vamos criar agora o teste para a subtração
59
TDD
@Test
public void deveriaSubtrairDoisValoresPassados() throws Exception{
Calculadora calculadora = new Calculadora();
int valorA = 5;
int valorB = 2;
int subtrai = calculadora.subtrai(valorA, valorB);
assertEquals(3, subtrai);
}
60
TDD
Método na classe Calculadora
public int subtrai(int valorA, int valorB) {
return valorA - valorB;
}
61
TDD
Divisão
@Test
public void deveriaDividirDoisValoresPassados() throws Exception {
int valorA = 6;
int valorB = 2;
Calculadora calculadora = new Calculadora();
int divisao = calculadora.divide(valorA, valorB);
assertEquals(3, divisao);
}
62
TDD
Na classe Calculadora
public int divide(int valorA, int valorB) {
return valorA / valorB;
}
63
TDD
E se eu mudar o teste para:
@Test
public void deveriaDividirDoisValoresPassados() throws Exception {
int valorA = 6;
int valorB = 0; // divisao por zero
Calculadora calculadora = new Calculadora();
int divisao = calculadora.divide(valorA, valorB);
assertEquals(?, divisao);
}
64
TDD
Eis um teste esperando por uma exceção
65
TDD
@Test
public void deveriaLancarUmaExcecaoIndicandoFalhaAoDividirUmNumeroPorZero() throws Exception {
int valorA = 6;
int valorB = 0;
Calculadora calculadora = new Calculadora();
int divisao = calculadora.divide(valorA, valorB);
assertEquals(0, divisao);
}
66
TDD
Podemos usar um parâmetro na própria anotação do JUnit (@Test) para indicar qual a exceção que estamos esperando receber
67
TDD
@Test(expected = ArithmeticException.class)
public void deveriaLancarUmaExcecaoIndicandoFalhaAoDividirUmNumeroPorZero() throws Exception {
int valorA = 6;
int valorB = 0;
Calculadora calculadora = new Calculadora();
calculadora.divide(valorA, valorB);
}
68
TDD
Agora sim temos a green bar novamente
69
TDD
E para a multiplicação, como fica?
70
Frameworks de Teste
71
TDD
TDD depende de um ambiente que facilite a execução de testes
Alguns exemplos de tais ambientes para as principais linguagens de programação
72
TDD
CUnit - teste de unidade para C
CPPUnit - teste de unidade para C++
73
TDD
JUnit - para Java
PyUnit - para Python
74
Questões restantes
75
TDD
TDD pode ser caixa preta ou caixa branca
Depende de como conduzimos o processo: se focamos em user stories ou em código, depende dos detalhes que usamos
76
TDD
TDD força uma abordagem de desenvolvimento bottom-up
isso ajuda a isolar faltas
77
Exercício
78
Exercício
Escrever casos de teste e a implementação para a sequência de Fibonacci, conforme a especificação:
F(0) = 0
F(1) = 1
F(2) = 1
F(n) = F(n-1) + F(n-2), para qualquer n maior que 2.
79
Exercício
Escrever o código da classe ValidDate usada para validar incrementos em datas
80
Exercício
81
Exercício
Com base na documentação fornecida, escreva os testes e o código para a classe implementando a interface AccountStack
82
Exercício
83
Referências
84
Referências
JORGENSEN, P. C. Software Testing: A Craftsman's Approach.
Cap. 19
85
Veja mais...
86
Veja mais
87
Desenvolvimento Dirigido a Testes
Prof. Alysson Filgueira Milanez
alysson.milanez@academico.ifpb.edu.br
Testes de Software