Desenvolvimento Dirigido por
     Testes com JUnit
               Adolfo Neto
             DAINF-UTFPR
     http://bit.ly/...
Resumo
   O objetivo desta palestra é apresentar como
  funciona o desenvolvimento dirigido por testes
       (TDD, do ter...
Abreviações
●   Test-driven development = TDD
●   Desenvolvimento dirigido por testes = DDT?
        –   Prefiro usar TDD,...
Pesquisa Informal
●   Quem aqui desenvolve (empresa/estudos)?
        –   Em Java?
●   Quem já sabe o que é TDD?
●   Quem ...
O que é TDD?
Exemplo Primeiro
●   Definições básicas:
    –   Testes
    –   Anotações
●   Exemplo no Eclipse
Roteiro: dez minutos (ideais) na vida de um
         programador que usa TDD
●   Escreve um teste         :|
●   Roda o te...
Exemplo: Calculadora
●   Estupidamente simples, de modo que qualquer um
    possa entender o código.
●   Calculadora que a...
Primeiro teste
●   Criar classe TestesCalculadora:


            public class TestesCalculadora
Primeiro teste
●   Criar método testaAdicao:


@Test
public void testaAdicao(){
 assertEquals("Resultado da soma de 3 e 4 ...
EXECUTAR O TESTE PARA VÊ-LO FALHAR!!!
Escrever código que faz passar no
              teste
●   Criar classe Calculadora
●   Criar método soma:


public static ...
EXECUTAR O TESTE E VÊ-LO DAR CERTO
Refatoração
●   Analisar o código escrito (inclusive o código de
    teste) e ver se há necessidade de refatoração.
Segundo teste
@Test
public void testaMultiplicacao(){
   assertEquals("Resultado da multiplicação de 3 e 4
é 12", 11, Calc...
Código para o segundo teste
public static int mult(int i, int j) {
    return i*j;
}
Terceiro teste
@Test
public void testaDivisao(){
 assertEquals("Resultado da divisão inteira de 4 por
3 é 1", 1, Calculado...
Código para o terceiro teste
public static int div(int i, int j) {
    return i/j;
}
Quarto teste
@Test(expected=ArithmeticException.class)
public void testaDivisaoPorZero(){
 assertEquals("Resultado da divi...
Código para o quarto teste
●   Não é necessário. Após executar o quarto teste
    verifica-se que a funcionalidade já está...
Quinto teste
@Test
public void testaSubtração(){
 assertEquals("Resultado da subtração de 1 por 2 é
-1", -1, Calculadora.s...
Código para o quinto teste
public static int sub(int i, int j) {
    return soma(i,-j);
}
Código para o quinto teste
                (refatorado)
public static int sub(int i, int j) {
    return i-j;
}
Sexto teste
@Test
public void testaExponenciacao(){
    assertEquals(1, Calculadora.exp(1,0));
}
Código para sexto teste
public static Object exp(int i, int j) {
return Math.pow(i, j);
}
Código para sexto teste
public static Object exp(int i, int j) {
return Math.pow(i, j);
}

RESULTADO: ERRO!
Math.pow retor...
Código para sexto teste
                (consertado)
public static int exp(int i, int j) {
    return (int)Math.pow(i, j);...
Complementando o sexto teste
@Test
public void testaExponenciacao(){
    assertEquals(1, Calculadora.exp(1,0));
    assert...
Sétimo teste
@Test(expected = ArithmeticException.class)
public void
testaExponenciacaoExpoentesNegativos() {
    assertEq...
Sétimo teste
●   FALHA com o código atual!

●   Não devemos permitir expoentes negativos.
Código para o sétimo (e último)
                 teste
public static int exp(int i, int j) {
if (j >= 0)
    return (int) ...
FIM DO EXEMPLO
Origem
●   Nasa – década de 1960
●   Manifesto Ágil (2001)
●   Kent Beck (Extreme Programming)
        –   Livros
        ...
Manifesto para Desenvolvimento Ágil de Software


    Estamos descobrindo maneiras melhores de desenvolver
      software,...
Manifesto para Desenvolvimento Ágil de Software




                    Ou seja, mesmo havendo valor nos itens à direita,
...
Frases
●   “Nunca escreva uma linha de código funcional
    sem um caso de teste quebrado.”
                           —Ke...
Observações
●   É uma técnica ágil
        –   Não obrigatoriamente deve ser feita em conjunto
             com uma metodo...
O PROCESSO EM IMAGENS
Fonte: http://upload.wikimedia.org/wikipedia/en/9/9c/Test-driven_development.PNG
The steps of Test-First Design




  TDD = Refactoring + TFD
    Fonte: http://www.agiledata.org/essays/tdd.html
Como fazer TDD com JUnit?
JUnit
                           *
●
    O JUnit é um arcabouço livre para a criação de
    testes unitários.
●   Dá apoio...
Detalhes Junit 4.x
●   Versão mais nova: 4.8.2
●   Disponível para Eclipse/Netbeans
●   Usa anotações
Classe de Testes
●   Uma classe exclusiva para testar
        –   Contém apenas código de testes
●   No Junit 4, não preci...
Anotação @Test
●   Colocar “@Test” antes da declaração do método
          –   @org.junit.Test
●   O método deve ser públi...
Anotação @Test
●   Escolher bons nomes para os métodos de teste
        –   Significativos
        –   Podem ser longos
● ...
Asserts
●   Métodos que são acompanhados pelo JUnit
●   Fazem a barra ficar verde ou vermelha
●   import static org.junit....
AssertEquals
●   2 parâmetros obrigatórios: Valor esperado e Valor
    calculado
●   1 parâmetro opcional: mensagem
●   Va...
Outros Asserts
●   assertArrayEquals
●   assertTrue e assertFalse
●   assertNull e assertNotNull
●   assertSame e assertNo...
Anotações @Before e @After
●   Usados quando temos muitos testes com os
    mesmos objetos
●   Métodos com @Before são exe...
Anotações @BeforeClass e
             @AfterClass
●   “Às vezes vários testes precisam compartilhar
    uma configuração c...
Capturando exceções: expected
●   Permite verificar se métodos corretamente lançam
    exceções em casos de erro
●   @Test...
Verificando performance: timeout
●    Permite verificar se um teste roda no tempo
     mínimo permitido
●    @Test(timeout...
Suítes de Testes
●   Permitem executar várias classes de testes de uma
    vez só.
●   Anotações:
    @RunWith: identifica...
Suítes de Testes
●   Exemplo:
@RunWith(Suite.class)
@SuiteClasses({TestesCalculadora.class,
TestesPerformanceCalculadora.c...
Mais
●   Testes parametrizados
        –   @RunWith(Parameterized.class)
        –   @Parameters
        –   Exemplo
Reflexões
Fluxo do Desenvolvimento




●   (a) fluxo com testes por último (tradicional)
●   (b) fluxo com testes antes (TDD)
Problemas
●   Nem todo mundo que acha que faz TDD
    realmente está fazendo TDD
        –   TDD diferente de testes unitá...
Concepções errôneas
1) “TDD é igual a testes automatizados”
2) “TDD significa (apenas) escrever todos os testes
  antes do...
Concepção correta
●   "TDD’s primary purpose (...) is design"
●   Mas no nome está “test ...”
●   Talvez o nome devesse se...
Parte Final
Conclusões
●   Por que fazer TDD?
●   TDD realmente aumenta a produtividade?
●   TDD realmente aumenta a qualidade do códi...
Mais sobre Métodos Ágeis
●   http://adolfoneto.wikidot.com/metodologias-ageis
        –   Ou adolfo neto métodos ágeis no ...
Divulgação
●   VII Semana de Informática da UTFPR
        –   http://twitter.com/seminfo7utfpr
●   Mestrado Profissional e...
Divulgação
●   Departamento Acadêmico de Informática
       –   Sistemas de Informação
       –   Engenharia de Computação...
Dúvidas, perguntas, sugestões?


            Adolfo Neto
          DAINF-UTFPR
  http://bit.ly/ADOLFO_NETO
Slides Extras
Testes mais complexos
●   Lógica multi-valorada:
        –   L3: 0: falso, 1/2, 1: verdadeiro
        –   ¬(0)=1, ¬(1/2)=1...
Mais Frases
●   “The act of writing a unit test is more an act of design than of
    verification. It is also more an act ...
Development Flow




●   Development flow:
       –   (a) traditional test-last and
       –   (b) test-driven development...
Blame
●   Name should be “test-driven design.”
Concepções errôneas
●   #1: TDD equals automated testing.
●   #2: TDD means write all tests first.
Concepção correta
●   "TDD’s primary purpose (...) is design"
Desenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com Junit
Upcoming SlideShare
Loading in …5
×

Desenvolvimento Dirigido por Testes com Junit

5,558 views

Published on

O objetivo desta palestra é apresentar como funciona o desenvolvimento dirigido por testes (TDD, do termo em inglês "test-driven development"), uma técnica de projeto de software utilizada principalmente em métodos ágeis para o desenvolvimento de software. Além disso, serão mostrados exemplos práticos de como desenvolver sofwtare utilizando TDD com o auxílio do framework open source JUnit (http://junit.sourceforge.net/).

Published in: Education
1 Comment
2 Likes
Statistics
Notes
  • Muito bom, professor. Gostei desse padrão de projeto!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
5,558
On SlideShare
0
From Embeds
0
Number of Embeds
22
Actions
Shares
0
Downloads
211
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide

Desenvolvimento Dirigido por Testes com Junit

  1. 1. Desenvolvimento Dirigido por Testes com JUnit Adolfo Neto DAINF-UTFPR http://bit.ly/ADOLFO_NETO Apresentado na VII SEMINFO Semana Acadêmica de Informática da UTFPR http://seminfo7.dainf.ct.utfpr.edu.br/
  2. 2. Resumo O objetivo desta palestra é apresentar como funciona o desenvolvimento dirigido por testes (TDD, do termo em inglês "test-driven development"), uma técnica de projeto de software utilizada principalmente em métodos ágeis para o desenvolvimento de software. Além disso, serão mostrados exemplos práticos de como desenvolver sofwtare utilizando TDD com o auxílio do framework open source JUnit (http://junit.sourceforge.net/).
  3. 3. Abreviações ● Test-driven development = TDD ● Desenvolvimento dirigido por testes = DDT? – Prefiro usar TDD, pois ninguém usa DDT, que tem outro significado em português ● Junit ● XUnit
  4. 4. Pesquisa Informal ● Quem aqui desenvolve (empresa/estudos)? – Em Java? ● Quem já sabe o que é TDD? ● Quem sabe o que são métodos ágeis? ● Quem conhece e já usou o Junit? – Na versão 4.* ● Alguém usa porque é padrão da empresa?
  5. 5. O que é TDD?
  6. 6. Exemplo Primeiro ● Definições básicas: – Testes – Anotações ● Exemplo no Eclipse
  7. 7. Roteiro: dez minutos (ideais) na vida de um programador que usa TDD ● Escreve um teste :| ● Roda o teste para vê-lo falhar (barra vermelha) ou sequer compilar :( ● Escreve a funcionalidade que faz o teste passar :| ● Roda o teste e o teste passa (barra verde) :) ● Refatora o código :| ● Roda o teste e o teste passa (barra verde) :)
  8. 8. Exemplo: Calculadora ● Estupidamente simples, de modo que qualquer um possa entender o código. ● Calculadora que aceita apenas números inteiros e cujos resultados são inteiros. ● Operações: adição, multiplicação, divisão, subtração, exponenciação.
  9. 9. Primeiro teste ● Criar classe TestesCalculadora: public class TestesCalculadora
  10. 10. Primeiro teste ● Criar método testaAdicao: @Test public void testaAdicao(){ assertEquals("Resultado da soma de 3 e 4 é 7", 7, Calculadora.soma(3,4)); }
  11. 11. EXECUTAR O TESTE PARA VÊ-LO FALHAR!!!
  12. 12. Escrever código que faz passar no teste ● Criar classe Calculadora ● Criar método soma: public static int soma (int a, int b){ return a+b; }
  13. 13. EXECUTAR O TESTE E VÊ-LO DAR CERTO
  14. 14. Refatoração ● Analisar o código escrito (inclusive o código de teste) e ver se há necessidade de refatoração.
  15. 15. Segundo teste @Test public void testaMultiplicacao(){ assertEquals("Resultado da multiplicação de 3 e 4 é 12", 11, Calculadora.mult(3,4)); }
  16. 16. Código para o segundo teste public static int mult(int i, int j) { return i*j; }
  17. 17. Terceiro teste @Test public void testaDivisao(){ assertEquals("Resultado da divisão inteira de 4 por 3 é 1", 1, Calculadora.div(4,3)); }
  18. 18. Código para o terceiro teste public static int div(int i, int j) { return i/j; }
  19. 19. Quarto teste @Test(expected=ArithmeticException.class) public void testaDivisaoPorZero(){ assertEquals("Resultado da divisão inteira de 4 por 0 é indefinido", 0, Calculadora.div(4,0)); }
  20. 20. Código para o quarto teste ● Não é necessário. Após executar o quarto teste verifica-se que a funcionalidade já está implementada!
  21. 21. Quinto teste @Test public void testaSubtração(){ assertEquals("Resultado da subtração de 1 por 2 é -1", -1, Calculadora.sub(1,2)); }
  22. 22. Código para o quinto teste public static int sub(int i, int j) { return soma(i,-j); }
  23. 23. Código para o quinto teste (refatorado) public static int sub(int i, int j) { return i-j; }
  24. 24. Sexto teste @Test public void testaExponenciacao(){ assertEquals(1, Calculadora.exp(1,0)); }
  25. 25. Código para sexto teste public static Object exp(int i, int j) { return Math.pow(i, j); }
  26. 26. Código para sexto teste public static Object exp(int i, int j) { return Math.pow(i, j); } RESULTADO: ERRO! Math.pow retorna double.
  27. 27. Código para sexto teste (consertado) public static int exp(int i, int j) { return (int)Math.pow(i, j); }
  28. 28. Complementando o sexto teste @Test public void testaExponenciacao(){ assertEquals(1, Calculadora.exp(1,0)); assertEquals(4, Calculadora.exp(2,2)); assertEquals(27, Calculadora.exp(3,3)); assertEquals(0, Calculadora.exp(0,3)); }
  29. 29. Sétimo teste @Test(expected = ArithmeticException.class) public void testaExponenciacaoExpoentesNegativos() { assertEquals(0, Calculadora.exp(2, -3)); assertEquals(0, Calculadora.exp(0, -3)); }
  30. 30. Sétimo teste ● FALHA com o código atual! ● Não devemos permitir expoentes negativos.
  31. 31. Código para o sétimo (e último) teste public static int exp(int i, int j) { if (j >= 0) return (int) Math.pow(i, j); else throw new ArithmeticException("Expoentes negativos não são permitidos!"); }
  32. 32. FIM DO EXEMPLO
  33. 33. Origem ● Nasa – década de 1960 ● Manifesto Ágil (2001) ● Kent Beck (Extreme Programming) – Livros – SUnit (para Smalltalk) – Junit (para Java) – xUnit
  34. 34. Manifesto para Desenvolvimento Ágil de Software Estamos descobrindo maneiras melhores de desenvolver software, fazendo-o nós mesmos e ajudando outros a fazerem o mesmo. Através deste trabalho, passamos a valorizar: Indivíduos e interações mais que processos e ferramentas Software em funcionamento mais que documentação abrangente Colaboração com o cliente mais que negociação de contratos Responder a mudanças mais que seguir um plano continua...
  35. 35. Manifesto para Desenvolvimento Ágil de Software Ou seja, mesmo havendo valor nos itens à direita, valorizamos mais os itens à esquerda. Kent Beck, Mike Beedle, Arie van Bennekum, Alistair Cockburn, Ward Cunningham, Martin Fowler, James Grenning, Jim Highsmith, Andrew Hunt, Ron Jeffries, Jon Kern, Brian Marick, Robert C. Martin, Steve Mellor, Ken Schwaber, Jeff Sutherland, Dave Thomas © 2001, os autores acima esta declaração pode ser copiada livremente em qualquer formato, mas somente integralmente através desta declaração.
  36. 36. Frases ● “Nunca escreva uma linha de código funcional sem um caso de teste quebrado.” —Kent Beck ● “Codificação com testes-primeiro não é uma técnica de testes.” —Ward Cunningham
  37. 37. Observações ● É uma técnica ágil – Não obrigatoriamente deve ser feita em conjunto com uma metodologia ágil. ● É uma técnica de projeto (design)! – Não é uma técnica para fazer testes.
  38. 38. O PROCESSO EM IMAGENS
  39. 39. Fonte: http://upload.wikimedia.org/wikipedia/en/9/9c/Test-driven_development.PNG
  40. 40. The steps of Test-First Design TDD = Refactoring + TFD Fonte: http://www.agiledata.org/essays/tdd.html
  41. 41. Como fazer TDD com JUnit?
  42. 42. JUnit * ● O JUnit é um arcabouço livre para a criação de testes unitários. ● Dá apoio à criação de testes automatizados na linguagem de programação Java. ● Foi criado por Eric Gamma e Kent Beck. ● Licença: Common Public License v 1.0 ● Código-fonte no GitHub * Arcabouço = framework
  43. 43. Detalhes Junit 4.x ● Versão mais nova: 4.8.2 ● Disponível para Eclipse/Netbeans ● Usa anotações
  44. 44. Classe de Testes ● Uma classe exclusiva para testar – Contém apenas código de testes ● No Junit 4, não precisa estender nenhuma outra classe (no 3 precisava) ● Geralmente colocada numa pasta separada (por exemplo, test) da pasta do código de produção (src) – Não precisa ser usada na geração do jar para o cliente
  45. 45. Anotação @Test ● Colocar “@Test” antes da declaração do método – @org.junit.Test ● O método deve ser público ● Exemplo: @Test public void nomeDoTeste(){ ... }
  46. 46. Anotação @Test ● Escolher bons nomes para os métodos de teste – Significativos – Podem ser longos ● Exemplos: – putThenGet (Kent Beck) – testInvokeSuiteOnNonSubclassOfTestCase (JUnit)
  47. 47. Asserts ● Métodos que são acompanhados pelo JUnit ● Fazem a barra ficar verde ou vermelha ● import static org.junit.Assert.*; ● Dicionário Michaelis: ● assert vt 1 afirmar, declarar, asseverar. 2 insistir (em um ponto de vista), defender, vindicar, reivindicar, pugnar por. to assert oneself a) perseverar(-se). b) reivindicar seus direitos e exigir seu reconhecimento. c) vencer. d) comportar-se de modo a chamar a atenção.
  48. 48. AssertEquals ● 2 parâmetros obrigatórios: Valor esperado e Valor calculado ● 1 parâmetro opcional: mensagem ● Variações - 6 assinaturas – tipos dos parâmetros: – long – double – Object
  49. 49. Outros Asserts ● assertArrayEquals ● assertTrue e assertFalse ● assertNull e assertNotNull ● assertSame e assertNotSame ● assertThat
  50. 50. Anotações @Before e @After ● Usados quando temos muitos testes com os mesmos objetos ● Métodos com @Before são executados antes de todo método com @Test ● Métodos com @After são executados antes de todo método com @Test
  51. 51. Anotações @BeforeClass e @AfterClass ● “Às vezes vários testes precisam compartilhar uma configuração computacionalmente cara (por exemplo, logar-se num BD). ● Apesar disto poder comprometer a independência dos testes, pode ser uma otimização necessária.” ● Métodos com @BeforeClass são executados uma única vez antes de todos os métodos com @Test ● Métodos com @AfterClass são executados uma única vez depois de todos os métodos com @Test
  52. 52. Capturando exceções: expected ● Permite verificar se métodos corretamente lançam exceções em casos de erro ● @Test(expected=NomedaClassedaExceção.class) ● Exemplo: @Test(expected=ArithmeticException.class) public void testaDivisaoPorZero(){ assertEquals("Resultado da divisão inteira de 4 por 0 é indefinido", 0, Calculadora.div(4,0)); }
  53. 53. Verificando performance: timeout ● Permite verificar se um teste roda no tempo mínimo permitido ● @Test(timeout=<tempo_em_milisegundos>) ● Exemplo: @Test(timeout=6) public void testaDesempenho(){ for (int i=1; i<100000;i++){ Calculadora.mult(i, i); }}
  54. 54. Suítes de Testes ● Permitem executar várias classes de testes de uma vez só. ● Anotações: @RunWith: identifica a classe que executa suítes de testes @SuiteClasses: lista as classes de teste a serem incluídas na suíte
  55. 55. Suítes de Testes ● Exemplo: @RunWith(Suite.class) @SuiteClasses({TestesCalculadora.class, TestesPerformanceCalculadora.class}) public class SuiteTestesCalculadora { }
  56. 56. Mais ● Testes parametrizados – @RunWith(Parameterized.class) – @Parameters – Exemplo
  57. 57. Reflexões
  58. 58. Fluxo do Desenvolvimento ● (a) fluxo com testes por último (tradicional) ● (b) fluxo com testes antes (TDD)
  59. 59. Problemas ● Nem todo mundo que acha que faz TDD realmente está fazendo TDD – TDD diferente de testes unitários automatizados ● Nem todo mundo que faz TDD está fazendo TDD da melhor forma possível ● Não há nenhuma comprovação científica de que TDD melhore a qualidade do código ou a produtividade dos desenvolvedores (mas existem algumas evidências)
  60. 60. Concepções errôneas 1) “TDD é igual a testes automatizados” 2) “TDD significa (apenas) escrever todos os testes antes do código” 3)“Se faço TDD não preciso testar depois” 4)“Todo o projeto do software consiste nos testes” 5)“Apenas testes unitários são necessários”
  61. 61. Concepção correta ● "TDD’s primary purpose (...) is design" ● Mas no nome está “test ...” ● Talvez o nome devesse ser projeto dirigido por testes (test-driven design). – Daí surgiu a variação/evolução BDD (Behaviour-Driven Development)
  62. 62. Parte Final
  63. 63. Conclusões ● Por que fazer TDD? ● TDD realmente aumenta a produtividade? ● TDD realmente aumenta a qualidade do código? – Estude bem como se faz e faça o teste você mesmo ● Outros frameworks para TDD em Java ● TDD em outras linguagens
  64. 64. Mais sobre Métodos Ágeis ● http://adolfoneto.wikidot.com/metodologias-ageis – Ou adolfo neto métodos ágeis no Google ● Destaque: – http://agilcoop.org.br/ – Agile Brazil 2010 http://www.agilebrazil.com/2010/pt/index.html
  65. 65. Divulgação ● VII Semana de Informática da UTFPR – http://twitter.com/seminfo7utfpr ● Mestrado Profissional em Computação Aplicada – http://www.ppgca.ct.utfpr.edu.br – http://bit.ly/PPGCA
  66. 66. Divulgação ● Departamento Acadêmico de Informática – Sistemas de Informação – Engenharia de Computação ● 88 vagas anuais em cada curso (desde 2010 via SISU/ENEM) ● Vagas de transferência todo semestre (geralmente não ocupadas) – Especialização em Tecnologia Java – Especialização em Gestão de Tecnologia da Informação
  67. 67. Dúvidas, perguntas, sugestões? Adolfo Neto DAINF-UTFPR http://bit.ly/ADOLFO_NETO
  68. 68. Slides Extras
  69. 69. Testes mais complexos ● Lógica multi-valorada: – L3: 0: falso, 1/2, 1: verdadeiro – ¬(0)=1, ¬(1/2)=1/2, ¬(1)=0 – ∧(1,1)=1 – E resto da tabela-verdade do E?
  70. 70. Mais Frases ● “The act of writing a unit test is more an act of design than of verification. It is also more an act of documentation than of verification. The act of writing a unit test closes a remarkable number of feedback loops, the least of which is the one pertaining to verification of function”. ● Bob Martin
  71. 71. Development Flow ● Development flow: – (a) traditional test-last and – (b) test-driven development/test-first flow.
  72. 72. Blame ● Name should be “test-driven design.”
  73. 73. Concepções errôneas ● #1: TDD equals automated testing. ● #2: TDD means write all tests first.
  74. 74. Concepção correta ● "TDD’s primary purpose (...) is design"

×