Download presentation
Presentation is loading. Please wait.
1
Exemplo de desenvolvimento com testes Prof. Dr. Alfredo Goldman Departamento de Ciência da Computação IME / USP 3 de Abril de 2003 VI Semana da Computação
2
03/04/2003VI Semana da Computação Problema com testes zTodos sabem: devem ser escritos; zPoucos o fazem, e por quê não ? yEstou com muita pressa zMas, isto cria um círculo vicioso: menos testes menos produtividade menos estabilidade mais pressão
3
03/04/2003VI Semana da Computação Como quebrar este ciclo zCriando um ambiente simples de testes zDepois de fazer os primeiros testes yo hábito vem para ficar zVamos mostrar como seria um desenvolvimento ideal.... yAtravés do JUnit... zMas, antes uma visão geral:
4
03/04/2003VI Semana da Computação JUnit - como funciona ? zArcabouço Java para testes de unidade yAPI para construir testes Classes básicas: Test, TestCase, TestSuite,... xUsam-se métodos tipo premissa: assertTrue(), assertEquals, fail(),... API para a execução de testes ( TestRunners ) xModo texto xModo gráfico
5
03/04/2003VI Semana da Computação Junit - origens e uso zCriado por K. Beck e E. Gamma zPadrão para testes em Java zPermite a execução automática de testes yExecuta os testes de forma silenciosa zDirigido a testes de unidade yMétodos yPode-se agrupar diversos testes
6
03/04/2003VI Semana da Computação Exemplo de uso Padrão use o método testXxx() para testar o método xxx() Utilize os métodos da classe TestCase yassertEquals( objeto1, objeto2); yassertTrue( varBool); yassertNotNull( objeto); yfail();
7
03/04/2003VI Semana da Computação JUnit na prática 1) O TestRunner recebe uma subclasse de TestCase ; 2) Descobre seus métodos (reflexão); 3) Para cada testXxx(); cria nova instância garante independência !! executa setUp(); testXxx(); tearDown(); 4) Possibilidades: término OK, falha, ou exceção
8
03/04/2003VI Semana da Computação Criando uma seqüência de testes Classe TestSuite Método addTest adiciona um teste a lista yEncontra os testes em uma classe (reflexão) new TestSuite( ClasseDeTestes.class); yPode-se juntar tudo TestSuite ts = new TestSuite(“tudo”); ts.addTest( pacote.Teste1.testeX); ts.addTest( ClasseDeTestes.suite());
9
03/04/2003VI Semana da Computação Premissas em Java (JDK 1.4) zNova palavra chave: assert assert (n > 0) : “n não é positivo”; zPodem ser desligadas facilmente zProvocam um AssertionError quando falham zPara usá-las: yjavac -source 1.4 Classe.java yjava -ea Classe
10
03/04/2003VI Semana da Computação JUnit e premissas: zPremissas são usadas dentro do código zOs testes JUnit ficam em classes separadas yNão tem acesso a partes encapsuladas zJUnit testa a partir da interface zPremissas podem verificar lógica interna
11
03/04/2003VI Semana da Computação Testes de desempenho JUnitPerf yMétodos para medir desempenho e escalabilidade TimedTest xMede, e limita o tempo do teste LoadTest xExecução concorrente, configuração por timers ThreadTest xExecuta o teste como uma thread separada
12
03/04/2003VI Semana da Computação Testes de Stress JMeter - testa nos limites yDe carga xPara diferentes tipos BDs, páginas WEB, objetos Java yGera gráficos Pode ser usado em conjunto com o JUnitPerf
13
03/04/2003VI Semana da Computação Testes de páginas WEB zTestar do ponto de vista do usuário yAtravés de páginas yTestes funcionais zExtensões do Junit HttpUnit e ServletUnit JXweb (especifica os testes em XML) XMLUnit yTodos são projetos sourceforge
14
03/04/2003VI Semana da Computação JUnit na prática: O programa zUm sistema para representar diversas moedas; zPara começar: algo simples.
15
class Money { private int fAmount; private String fCurrency; public Money(int amount, String currency) { fAmount = amount; fCurrency = currency; } public int amount() { return fAmount; } public String currency() { return fCurrency; }
16
03/04/2003VI Semana da Computação Para somar dois “Moneys” da mesma moeda (currency): public Money add(Money m) { return new Money(amount()+m.amount(), currency()); }
17
03/04/2003VI Semana da Computação Questão de hábito zCode a little, test a little, code a little, test a little.... zJá temos um objeto, vamos testá-lo !! zNo JUnit os testes devem ser subclasses de TestCase
18
public class MoneyTest extends TestCase { //… public void testSimpleAdd() { Money m12CHF= new Money(12, "CHF"); // (1) Money m14CHF= new Money(14, "CHF"); Money expected= new Money(26, "CHF"); Money result= m12CHF.add(m14CHF); // (2) Assert.assertTrue(expected.equals(result)); // (3)assertTrue } O testSimpleAdd() consiste em: Código para criar os objetos; Código para usar os objetos; Código para verificar os resultados. Falta fazer a sobrecarga de equals
19
public void testEquals() { Money m12CHF= new Money(12, "CHF"); Money m14CHF= new Money(14, "CHF"); Assert.assertTrue(!m12CHF.equals(null)); Assert.assertEquals(m12CHF, m12CHF); Assert.assertEquals(m12CHF, new Money(12, "CHF")); // (1) Assert.assertTrue(!m12CHF.equals(m14CHF)); } // lembrete: o equals do object volta true se os // objetos comparados são o mesmo. Mas antes um teste para o equals
20
03/04/2003VI Semana da Computação Agora sim public boolean equals(Object anObject) { if (anObject instanceof Money) { Money aMoney = (Money) anObject; return aMoney.currency().equals(currency()) && amount() == aMoney.amount(); } return false; } // faltou sobrecarregar o método hashCode...
21
03/04/2003VI Semana da Computação Mas, já apesar dos testes serem pequenos já há código duplicado... public class MoneyTest extends TestCase { private Money f12CHF; private Money f14CHF; protected void setUp() {setUp f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); }
22
03/04/2003VI Semana da Computação Agora os testes podem ser rescritos como: public void testEquals() { assert(!f12CHF.equals(null)); assertEquals(f12CHF, f12CHF); assertEquals(f12CHF, new Money(12, "CHF")); assert(!f12CHF.equals(f14CHF)); } public void testSimpleAdd() { Money expected= new Money(26, "CHF"); Money result= f12CHF.add(f14CHF); assert(expected.equals(result)); }
23
03/04/2003VI Semana da Computação Próximos passos zDefinir como rodar um teste individual; zDefinir como rodar uma seqüência de testes.
24
// forma estática, com classe interior TestCase test= new MoneyTest("simple add") { public void runTest() { testSimpleAdd(); } }; // forma dinâmica, usa reflexão TestCase test= new MoneyTest("testSimpleAdd");
25
03/04/2003VI Semana da Computação Pode-se automatizar testes zCriando uma seqüência de testes public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(new MoneyTest("testEquals")); suite.addTest(new MoneyTest("testSimpleAdd")); return suite; }
26
03/04/2003VI Semana da Computação Pode-se automatizar testes zOu apenas: public static Test suite() { return new TestSuite(MoneyTest.class); } Agora, um pouco de JUnit na prática.
27
03/04/2003VI Semana da Computação Continuando o projeto Deve-se poder guardar diversos tipos de moeda class MoneyBag { private Vector fMoneis= new Vector(); MoneyBag(Money m1, Money m2) { appendMoney(m1); appendMoney(m2); } MoneyBag(Money bag[]) { for (int i= 0; i < bag.length; i++) appendMoney(bag[i]); }
28
protected void setUp() { f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); f7USD= new Money( 7, "USD"); f21USD= new Money(21, "USD"); fMB1= new MoneyBag(f12CHF, f7USD); fMB2= new MoneyBag(f14CHF, f21USD); } Para os testes deve se criar também objetos do novo tipo
29
public void testBagEquals() { assert(!fMB1.equals(null)); assertEquals(fMB1, fMB1); assert(!fMB1.equals(f12CHF)); assert(!f12CHF.equals(fMB1)); assert(!fMB1.equals(fMB2)); } Devem se criar novos testes, mas os testes antigos continuam lá E devem continuar funcionando...
30
public Money add(Money m) { if (m.currency().equals(currency()) ) return new Money(amount() + m.amount(), currency()); return new MoneyBag(this, m); } // ops MoneyBag != Money.... Agora podemos melhorar o método add Agora existem duas representações de dinheiro... interface IMoney { public abstract IMoney add(IMoney aMoney); //… }
31
Mas, ainda não temos testes para tipos mistos... public void testMixedSimpleAdd() { // [12 CHF] + [7 USD] == {[12 CHF][7 USD]} Money bag[]= { f12CHF, f7USD }; MoneyBag expected= new MoneyBag(bag); assertEquals(expected, f12CHF.add(f7USD)); } Os outros testes seguem o mesmo padrão: testBagSimpleAdd - soma MoneyBag com Money testSimpleBagAdd - soma Money com MoneyBag testBagBagAdd - soma dois MoneyBags
32
Mais testes estão disponíveis: public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(new MoneyTest("testMoneyEquals")); suite.addTest(new MoneyTest("testBagEquals")); suite.addTest(new MoneyTest("testSimpleAdd")); suite.addTest(new MoneyTest("testMixedSimpleAdd")); suite.addTest(new MoneyTest("testBagSimpleAdd")); suite.addTest(new MoneyTest("testSimpleBagAdd")); suite.addTest(new MoneyTest("testBagBagAdd")); return suite; } Agora sim vamos implementá-los...
33
class Money implements IMoney { public IMoney add(IMoney m) { return m.addMoney(this); } //… } class MoneyBag implements IMoney { public IMoney MoneyBag.add(IMoney m) { return m.addMoneyBag(this); } //… } //… IMoney addMoney(Money aMoney); IMoney addMoneyBag(MoneyBag aMoneyBag); }
34
Em Money. public IMoney addMoney(Money m) { if (m.currency().equals(currency())) return new Money(amount()+m.amount(), currency()); return new MoneyBag(this, m); } public IMoney addMoneyBag(MoneyBag s) { return s.addMoney(this); }
35
Em MoneyBag. public IMoney addMoney(Money m) { return new MoneyBag(m, this); } public IMoney addMoneyBag(MoneyBag s) { return new MoneyBag(s, this); } Surge um problema.... E se retira-se 12CHF de um MoneyBag com 12CHF ???
36
Primeiro o teste... public void testSimplify() { // {[12 CHF][7 USD]} + [-12 CHF] == [7 USD] Money expected= new Money(7, "USD"); assertEquals(expected, fMS1.add(new Money(-12, "CHF"))); }
37
Depois o código. public IMoney addMoney(Money m) { return (new MoneyBag(m, this)).simplify(); } public IMoney addMoneyBag(MoneyBag s) { return (new MoneyBag(s, this)).simplify(); } private IMoney simplify() { if (fMonies.size() == 1) return (IMoney)fMonies.firstElement() return this; }
38
03/04/2003VI Semana da Computação Desenvolvimento com testes zTestes devem ser escritos assim que possível; zTestes devem ser adaptados segundo as mudanças; zDeixe os testes antigos rodando; zQuando surgem novas idéias (simplify), crie testes, veja se funcionam, e se necessário altere o código.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.