Exemplo de desenvolvimento com testes (JUNIT - estudo de caso) Alfredo Goldman.

Slides:



Advertisements
Apresentações semelhantes
Classes Abstratas e Interfaces
Advertisements

Utilitários Marco Antonio. Enum Como o nome sugere, é uma enumeração de opções para uma determinada situação A principal vantagem é limitar as opções.
Projeto de Sistemas de Software
Padrão de Projeto Interpreter
Projeto de Sistemas de Software Trabalho de Padrões de Projeto
Kleinner Farias e Raphael do Vale
Padrão de Projeto Iterator
Orientação a Objetos: Modificador Final para Métodos e Classes
Herança, sobrecarga e ligação dinâmica zHerança zReferência super zSobrecarga de métodos zSobreposição zLigação dinâmica de métodos zfinal.
Polimorfismo e Acoplamento Dinâmico
Walfredo Cirne walfredo.dsc.ufpb.br
Walfredo Cirne walfredo.dsc.ufpb.br
Test Driven Development
JAVA ENUMS © 2009 by Jorge L. de Souza Leão março de 2009 PEE - COPPE/UFRJ.
UMA ABORDAGEM SOBRE ORIENTAÇÃO A OBJETOS!
Aula 8 Polimorfismo.
A linguagem C#.
Classes & Objectos em JAVA5
Métodos Programação II
CRIANDO OBJETOS EM JAVA
Linguagem Técnica II Testes Automatizados Aula 04 Prof
O Mecanismo de Threads em Java 2. Criar uma classe herdeira da super classe Thread public class minhaThread extends Thread{ public class minhaThread extends.
Programação Orientada a Objetos com Java
Singleton e Adapter Professor: Nazareno Andrade
DBUnit Framework Componentes: Fábio Gomes Claver Pari Eni Conde
Plano de teste.
Atributos, Encapsulamento e Interface em Java
OPERADORESOPERADORES SCJP – Otimize-TI. Operadores Java Resultado: Maioria das operações é um booleano ou numérico. Não podem ser sobrecarregados (Existem.
Utilizando Testes Unitários Gleibson Rodrigo “dartanham” Fontes: antiga apresentação de testes da disciplina de ESS e na curso de testes do PDesigner.
Desenvolvimento Orientado a Componentes e Reuso
JUnit “Keep the bar green to keep the code clean” JUnit Site.
Jass - Java with assertions Sérgio Soares. zAssertions descrevem propriedades que devem ser verdadeiras em determinados pontos da execução do programa.
Um Framework Para Testes
Paulo Borba Centro de Informática Universidade Federal de Pernambuco Classes Abstratas e Interfaces.
Testes de Unidade Usando JUnit
Introdução – Teste de Unidade usando JUnit
Os métodos equals() e hashCode()
Orientação a Objetos e Java Graduação em Ciência da Computação
Professora Lucélia Oliveira
Paulo Borba Centro de Informática Universidade Federal de Pernambuco
Pilhas Profa. Nádia Félix.
Curso de Aprendizado Industrial Desenvolvedor WEB Disciplina: Programação Orientada a Objetos I Professora: Cheli Mendes Costa This.
Wagner Santos C. de Jesus
Aula Prática 1 Monitoria IP/CC (~if669). Verificação Dinâmica de Tipos Métodos de superclasses e subclasses: Uso de métodos de subclasses quando se é.
UTFPR – Campus Curitiba - DAELN Cursos de Eng. Eletrônica/Eng
Java Kickstart, day 2 Semelhanças com linguagem C.
Aula Prática 4 Monitoria IP/CC (~if669).
1 Marcio de Carvalho Victorino JAVA. 2 Declaração de Atributos [ ] [transient] [volatile] [static] [final] ; controle de acesso –public, package (default),
Classes Abstratas e Interface
Módulo 9 Strings , Coleções e I/O
Programação I Aula 4 (Expressões Booleanas e Expressões de Seleção) Prof. Gilberto Irajá Müller Última atualização 17/3/2009.
Certificação Marco Antonio. Introdução A compreensão desse capítulo é muito importante pois trata de um assunto essencial em qualquer linguagem de programação,
Coleções em Java - Parte 2
Programação para Dispositivos Móveis Prof. Wallace Borges Cristo.
Copyright 1998, Departamento de Informática da UFPE. Todos os direitos reservados sob a legislação em vigor. Variáveis e métodos estáticos, Passagem de.
Daniel Cukier – IME - USP 1 Junit 4.0 Daniel Cukier – IME – USP MAC5700.
1 JUnit. 2 Por que testar? Qualidade: Código testado é mais confiável –Como saber se o recurso funciona sem testar? Coragem para mudar: o programador.
Classes abstratas São classes das quais não se pode instanciar objetos. São classes das quais não se pode instanciar objetos. Seu objetivo é ser herdada.
Orientação a Objetos e Java Graduação em Ciência da Computação  Centro de Informática, UFPE Alexandre Mota
Orientação a Objetos e Java Graduação em Ciência da Computação  Centro de Informática, UFPE Alexandre Mota
J U nit Um Framework Para Testes. Motivação  Todos os programadores sabem que devem testar seu código  Quanto mais curto o prazo menos testes são realizados.
Teste De Sistemas Web Com JUnit E Suas Extensões
Implementação Orientada a Objetos – Aula 04 Métodos, parâmetros e retorno Prof. Danielle Martin/Marcia Bissaco Universidade de Mogi das Cruzes
Orientação a Objetos e Java Graduação em Ciência da Computação  Centro de Informática, UFPE Alexandre Mota
Análise Contextual Tem o objetivo de verificar se o programa está de acordo com as restrições contextuais da linguagem fonte.
Aula 7 – Padrão Abstract Factory
Estrutura de Dados Prof. André Cypriano M. Costa
Herança e Polimorfismo Prof. Gustavo Wagner (Alterações) Prof. Tiago Massoni (Slides Originais) Desenvolvimento de Sistemas FATEC-PB  Centro de Informática,
Linguagem de Programação – Aula 04 Prof. Me. Ronnison Reges Vidal.
Usando JUnit.
Transcrição da apresentação:

Exemplo de desenvolvimento com testes (JUNIT - estudo de caso) Alfredo Goldman

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

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

O programa zUm sistema para representar diversas moedas; zPara começar: algo simples.

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

Para somar dois Moneys da mesma moeda (currency): public Money add(Money m) { return new Money(amount()+m.amount(), currency()); }

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

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

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

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

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

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

Próximos passos zDefinir como rodar um teste individual; zDefinir como rodar uma seqüência de testes.

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

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

Pode-se automatizar testes zOu apenas: public static Test suite() { return new TestSuite(MoneyTest.class); } Agora, um pouco de JUnit na prática.

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

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

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

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

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

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

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

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

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

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

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

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.