View
16
Download
0
Category
Preview:
Citation preview
Análise e Projeto Orientados a Objetos
Desenvolvimento Guiado por Testes (TDD)
Diretoria Acadêmica de Gestão e Tecnologia da Informação
TDD
• Test Driven Development (desenvolvimento guiado por testes) é uma prática de teste e de projeto software.
• TDD baseia-se num ciclo que:
– Escreve o teste antes do código de produção.
– Valida o teste.
– Melhora de forma contínua o código de teste e de produção.
2
Benefícios
• Garante que os testes são escritos.
• Produz código fácil de ser testado, ou seja, coeso e com baixo acoplamento.
3
Ciclo do TDD
4
Ciclo do TDD
• Escreva um teste.
• Valide o teste:
– Faça o teste falhar.
– Faça o teste passar com uma implementação mínima.
• Refatore (melhore) o código (de testes e/ou de produção.
5
Passos de bebê
• Os avanços devem ser gradativos e seguros.
• A atividade seguinte só deve ser iniciada assim que a atividade atual estiver 100% em ordem.
– Nunca deixe de validar o teste!
6
Exemplo – classe Fração
• Classe para representar frações matemáticas.
• Requisitos:
– Instâncias imutáveis.
– Denominador não pode assumir o valor zero.
– As frações sempre devem ser criadas na forma reduzida (simplificada).
7
Testes inicialmente planejados
• Denominador igual a zero.
• Denominador diferente de zero (parece ser mais fácil)
• Redução da fração (mais difícil)
8
Testes inicialmente planejados
• Teste 2: denominador igual a zero.
• Teste 1: denominador diferente de zero (parece ser mais fácil)
• Teste 3: redução da fração (mais difícil)
9
Teste 1 – classe de testes
• Não compila
10
package fracao;
import org.junit.Assert;import org.junit.Test;
public class FracaoTest {@Testpublic void testConstrutor_1(){Fracao f = new Fracao(2, 3);Assert.assertEquals(2, f.getNumerador());Assert.assertEquals(3, f.getDenominador());
}}
Teste 1 – classe Fração
• Implementar o necessário para compilar e falhar o teste
11
package fracao;
public class Fracao {private int numerador;private int denominador;public Fracao(int n, int d){}public int getNumerador(){return numerador;
}public int getDenominador(){return denominador;
}}
Teste 1 – classe Fração
• Implementar o necessário para compilar e falhar o teste
12
package fracao;
public class Fracao {private int numerador;private int denominador;public Fracao(int n, int d){}public int getNumerador(){return numerador;
}public int getDenominador(){return denominador;
}}
Teste 1 – classe Fração
• Passar o teste da maneira mais simples
13
public class Fracao {private int numerador;private int denominador;public Fracao(int n, int d){this.numerador = 2;this.denominador = 3;
}...
}
Teste 1 – classe Fração
• Refatoração
14
public class Fracao {private final int numerador;private final int denominador;public Fracao(int n, int d){this.numerador = n;this.denominador = d;
}...
}
Teste 2 – classe de testes
• Escrever teste e vê-lo falhar
15
@Test(expected=IllegalArgumentException.class)public void testConstrutor_2(){Fracao f = new Fracao(2, 0);
}
Teste 2 – classe Fração
• Passar o teste da maneira mais simples
16
public Fracao(int n, int d){throw new IllegalArgumentException();//this.numerador = n;//this.denominador = d;
}
Teste 2 – classe Fração
• Refatoração: passar todos os testes
17
public Fracao(int n, int d){if(d == 0)throw new IllegalArgumentException
("Denominador não pode ser zero");this.numerador = n;this.denominador = d;
}
Teste 3 – classe de testes
• Deve falhar com a implementação atual
18
@Testpublic void testConstrutor_3(){Fracao f = new Fracao(2, 4);Assert.assertEquals(1, f.getNumerador());Assert.assertEquals(2, f.getDenominador());
}
Teste 3 – classe Fração
• Passar o teste da maneira mais simples
19
public Fracao(int n, int d){if(d == 0)throw new IllegalArgumentException
("Denominador não pode ser zero");//this.numerador = n;//this.denominador = d;this.numerador = 1;this.denominador = 2;
}
Teste 3 – classe Fração
• Passar todos os testes
20
public Fracao(int n, int d){if(d == 0)throw new IllegalArgumentException
("Denominador não pode ser zero");int mdc = 1;for(int i = Math.min(n, d); i >= 2; i--)if(n % i == 0 && d % i == 0){
mdc = i;break;
}this.numerador = n / mdc;this.denominador = d / mdc;
}
Teste 3 – classe Fração
• Refatoração
21
public Fracao(int n, int d){if(d == 0)throw new IllegalArgumentException
("Denominador não pode ser zero");int mdc = mdc(n, d);this.numerador = n / mdc;this.denominador = d / mdc;
}private int mdc(int a, int b){int mdc = 1;for(int i = Math.min(a, b); i >= 2; i--)if(a % i == 0 && b % i == 0){
mdc = i;break;
}return mdc;
}
Teste 3 – classe Fração
• Refatoração
22
public Fracao(int n, int d){if(d == 0)throw new IllegalArgumentException
("Denominador não pode ser zero");int mdc = mdc(n, d);this.numerador = n / mdc;this.denominador = d / mdc;
}private int mdc(int a, int b){int mdc = 1;for(int i = Math.min(a, b); i >= 2; i--)if(a % i == 0 && b % i == 0){
mdc = i;break;
}return mdc;
}
Teste 4 – classe de testes
• Novo teste de redução
23
@Testpublic void testConstrutor_4(){Fracao f = new Fracao(50, 30);Assert.assertEquals(5, f.getNumerador());Assert.assertEquals(3, f.getDenominador());
}
Teste 4 – classe Fração
• Fazer o teste falhar
24
public Fracao(int n, int d){if(d == 0)throw new IllegalArgumentException
("Denominador não pode ser zero");//int mdc = mdc(n, d);int mdc = 1; this.numerador = n / mdc;this.denominador = d / mdc;
}
Teste 4 – classe Fração
• Fazer os testes passarem
25
public Fracao(int n, int d){if(d == 0)throw new IllegalArgumentException
("Denominador não pode ser zero");int mdc = mdc(n, d);this.numerador = n / mdc;this.denominador = d / mdc;
}
Referências
• Beck, Kent. TDD: desenvolvimento guiado por testes. Porto Alegre: Bokman, 2010.
• Teles, Vinícius M. Desenvolvimento orientado a testes. Disponível em <http://www.desenvolvimentoagil.com.br/xp/praticas/tdd/>.
• Aniche, Maurício. TDD. Disponível em <http://tdd.caelum.com.br/>
26
Informações bibliográficas
• Autor: Alexandre G. de Lima
• Data: fevereiro de 2016.
• Local: Natal-RN
27
Recommended