ferramentas testes2003

38
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

Upload: natalio-rodrigues

Post on 22-Jun-2015

44 views

Category:

Education


1 download

DESCRIPTION

teste slide

TRANSCRIPT

Page 1: Ferramentas testes2003

Exemplo de desenvolvimento com testes

Prof. Dr. Alfredo Goldman

Departamento de Ciência da ComputaçãoIME / USP

3 de Abril de 2003VI Semana da Computação

Page 2: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Problema com testes

Todos sabem: devem ser escritos;Poucos o fazem, e por quê não ?

Estou com muita pressaMas, isto cria um círculo vicioso:

menos testes

menos produtividademenos estabilidade

mais pressão

Page 3: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Como quebrar este ciclo

Criando um ambiente simples de testesDepois de fazer os primeiros testes

o hábito vem para ficarVamos mostrar como seria um

desenvolvimento ideal.... Através do JUnit...

Mas, antes uma visão geral:

Page 4: Ferramentas testes2003

03/04/2003 VI Semana da Computação

JUnit - como funciona ?

Arcabouço Java para testes de unidade API para construir testes

Classes básicas: Test, TestCase, TestSuite,...Usam-se métodos tipo premissa:

• assertTrue(), assertEquals, fail(), ...

API para a execução de testes (TestRunners)Modo textoModo gráfico

Page 5: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Junit - origens e uso

Criado por K. Beck e E. GammaPadrão para testes em JavaPermite a execução automática de

testes Executa os testes de forma silenciosa

Dirigido a testes de unidade Métodos Pode-se agrupar diversos testes

Page 6: Ferramentas testes2003

03/04/2003 VI 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 assertEquals( objeto1, objeto2); assertTrue( varBool); assertNotNull( objeto); fail();

Page 7: Ferramentas testes2003

03/04/2003 VI 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

Page 8: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Criando uma seqüência de testes

Classe TestSuite Método addTest adiciona um teste a lista Encontra os testes em uma classe

(reflexão)new TestSuite( ClasseDeTestes.class);

Pode-se juntar tudoTestSuite ts = new TestSuite(“tudo”);

ts.addTest( pacote.Teste1.testeX);

ts.addTest( ClasseDeTestes.suite());

Page 9: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Premissas em Java (JDK 1.4)

Nova palavra chave: assert assert (n > 0) : “n não é positivo”;

Podem ser desligadas facilmenteProvocam um AssertionError quando

falhamPara usá-las:

javac -source 1.4 Classe.java java -ea Classe

Page 10: Ferramentas testes2003

03/04/2003 VI Semana da Computação

JUnit e premissas:

Premissas são usadas dentro do código

Os testes JUnit ficam em classes separadas Não tem acesso a partes encapsuladas

JUnit testa a partir da interfacePremissas podem verificar lógica interna

Page 11: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Testes de desempenho

JUnitPerf Métodos para medir desempenho e

escalabilidade TimedTest

Mede, e limita o tempo do teste

LoadTestExecução concorrente, configuração por timers

ThreadTestExecuta o teste como uma thread separada

Page 12: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Testes de Stress

JMeter - testa nos limites De carga

Para diferentes tipos BDs, páginas WEB, objetos Java

Gera gráficos Pode ser usado em conjunto com o JUnitPerf

Page 13: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Testes de páginas WEB

Testar do ponto de vista do usuário Através de páginas Testes funcionais

Extensões do Junit HttpUnit e ServletUnit JXweb (especifica os testes em XML) XMLUnit Todos são projetos sourceforge

Page 14: Ferramentas testes2003

03/04/2003 VI Semana da Computação

JUnit na prática: O programa

Um sistema para representar diversas moedas;

Para começar: algo simples.

Page 15: Ferramentas testes2003

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; }}

Page 16: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Para somar dois “Moneys” da mesma moeda (currency):

public Money add(Money m) { return new Money(amount()+m.amount(), currency());}

Page 17: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Questão de hábito

Code a little, test a little, code a little, test a little....

Já temos um objeto, vamos testá-lo !!

No JUnit os testes devem ser subclasses de TestCase

Page 18: Ferramentas testes2003

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) }}

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

Page 19: Ferramentas testes2003

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

Page 20: Ferramentas testes2003

03/04/2003 VI 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...

Page 21: Ferramentas testes2003

03/04/2003 VI 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() { f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); }}

Page 22: Ferramentas testes2003

03/04/2003 VI 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));}

Page 23: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Próximos passos

Definir como rodar um teste individual;

Definir como rodar uma seqüência de testes.

Page 24: Ferramentas testes2003

// 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");

Page 25: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Pode-se automatizar testes

Criando 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;}

Page 26: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Pode-se automatizar testes

Ou apenas:

public static Test suite() {return new TestSuite(MoneyTest.class);}

Agora, um pouco de JUnit na prática.

Page 27: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Continuando o projetoDeve-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]); }}

Page 28: Ferramentas testes2003

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

Page 29: Ferramentas testes2003

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...

Page 30: Ferramentas testes2003

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); //…}

Page 31: Ferramentas testes2003

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

Page 32: Ferramentas testes2003

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...

Page 33: Ferramentas testes2003

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);}

Page 34: Ferramentas testes2003

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);}

Page 35: Ferramentas testes2003

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 com12CHF ???

Page 36: Ferramentas testes2003

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")));}

Page 37: Ferramentas testes2003

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;}

Page 38: Ferramentas testes2003

03/04/2003 VI Semana da Computação

Desenvolvimento com testes

Testes devem ser escritos assim que possível;

Testes devem ser adaptados segundo as mudanças;

Deixe os testes antigos rodando;Quando surgem novas idéias (simplify),

crie testes, veja se funcionam, e se necessário altere o código.