Aislan Fernandes
           @aislanfp
aislanfp@gmail.com
Roteiro
 Contextos
 Conceitos
 Ferramentas
 Técnicas
 Demonstração
Referências
 KOSKELA, Lasse. Test Driven: Pratictal
  TDD and Acceptance TDD for Java
  Developers. Manning. Greenwich, 2008.
 FOWLER, Martin. Refactoring:
  Improving the Design of Existing Code.
  Addison-Wesley. 1999.
 BECK, Kent. Programação Extrema
  (XP) Explicada – Acolha as mudanças.
  Porto Alegre: Bookman, 2004.
Contexto Maior (Organização)
    Software            Mudanças
                           Custo




               Escopo
                        Projeto       Tempo




                          Qualidade


                                              Engenharia
                                              de Software
Contexto Menor (Equipe)
     “Mudança é uma constante, o problema é falta de habilidade”*


 O custo da mudança não é
  exponencial mas achatado                         Metodologias Ágeis
 Não há aquele código difícil de
  modificar , acompanhado de
  medo e da falta de testes para                   Iterativo e Incremental
  verificar se houve efeito
  colateral.                                        XP     Scrum    PU**
 TDD é um ingrediente chave 

                  * BECK, 2004; **LARMAN, Craig.
Conceito
 TDD não é desenvolvimento com testes!




    Regra 10 de Myers
     Quanto mais cedo
     defeito descoberto
   menor custo de correção
Conceito
 TDD = fazer certo
 TDD = Test-code-refactor
 TDD = Red-green-refactor
 TDD = Test Driven Development
 TDD = Test Driven Design
 TDD = Test-First Programming

 “Infectado por Testes”* = não codificar sem teste antes

    Acceptance TDD (ATDD) = fazer a coisa certa ≈ BDD


                    * Erich Gamma
Objetivos*  Benefícios
 Encorajar um bom design                                 Testes
 Produzir código testável
 Evitar engenharia excessiva ou pesada                   Revelar falhas

 Evitar código mal escrito, difícil de
  entender e de mudar                                     Mostrar que
                                                          faz o que deve
 Cortar o tempo em tarefas não                           ser feito

  produtivas:
     Debugging                               100%        Revelar design

     Resolvendo bugs
     Entendendo código ilegível                          Especificar em
                                                          exemplos
        Programar e testar ao mesmo tempo é mais rápido
                   do que apenas programar!
                  * KOSKELA, 2008
Funcionamento
 Ciclo TDD  Escreva o teste, e somente então escreva o
  código para passar no teste. Por fim, transforme o design
  atual num melhor (refactor).
 Repetição dos ciclos TDD = design evolucionário
    Quando parar?
    Ponto de satisfação ≈ conhecimento de padrões de projeto



                        Test        Code       Refactor


        “Os testes me dão a chance de pensar sobre o que eu quero
                 independentemente da implementação.”*

                  * BECK, 2004
Design Evolucionário
 Feedback imediato  design somente evolui quando
 efetiva e objetivamente o usamos, escrevendo o teste
 antes*
   Escrever teste = decidir sobre design
 Focado no presente  menos custoso
    Uso de code coverage  gordura?
    Priorizado em histórias
 “Quando você acrescenta mais ao projeto hoje, você
aumenta a sobrecarga do sistema. Há mais coisas para
           testar, entender e explicar”**
      “Os problemas de hoje já são suficientes”**
                   * KOSKELA, 2008 ** BECK, 2004
Design Evolucionário
 Testar + Refatorar  Escrever testes antes promove um
 certo nível de testabilidade, porém é preciso estar
 consciente de não construir um que funciona agora
 mas pode explodir em breve *

                            Design Testável
     Prefira composição em vez                         Procure isolar e injetar
              de herança                                   dependências

                                  Melhor
                                                                     Melhor testabilidade e
       Mais código      testabilidade, flexibilidade   Mais código
                                                                         manutenção
                              e manutenção



                     * KOSKELA, 2008
Refactoring
 Técnica para reestruturar um código
  existente, alterando sua estrutura interna sem alterar
  seu comportamento externo*
 Disciplinado
   Não prevemos e nem nos preparamos para problemas de
    design antes de ter um em mãos, evitando criar mais
    problemas
 Padronizado
    Remoção de código duplicado
    Problemas específicos
                  * FOWLER, 1999
Ferramentas
 Frameworks
    EasyMock
    JUnit
    DBUnit


 Integração Contínua
    Hudson              Análise Estática
                            EMMA  Code
    TeamCity
                             Coverage
    Apache Continuum
                            PMD  Duplicação e
                             padrões
EasyMock                                   Mocks


                                            Fakes
 Má Prática  classes
  vazias como mocks
 Foco  preocupação                        Stubs

  com teste e não com
  ambiente                                 ITranslator mockTranslator =
                                         createMock(ITranslator.class);
 Problemas  erros de    Greeting greeting = new Greeting(mockTranslator);
                           expect(mockTranslator.translate("English",
  compilação nos testes     "Hindi", "Hello")).andReturn("Namaste");
  quando mudam as                              replay(mockTranslator);
                                              assertEquals("Namaste Paulo",
  interfaces                            greeting.sayHello("Hindi", "Paulo"));
                                                verify(mockTranslator);
Integração Contínua
 Médio e longo prazo  repositório de testes difíceis de
 gerenciar individualmente
   Não é possível executar todos os testes
   Executar suite de testes a cada pequena mudança
    permite um feedback imediato
Implementação
           Decomposição                    Programação
            de requisito                   por intenção

 Decomposição de Requisito*  criar uma lista de
 testes em vez de tarefas
   Foco no que é necessário e não no que poderia ser feito
 Programação por Intenção*  escrever teste sem
 código algum, como se o código existisse!
   Foco no que necessitamos e não no que temos

       Teste é algo um pouco mais concreto, mais executável, mais
                     exemplificativo do que o requisito
                * KOSKELA, 2008
Implementação
 Qual teste selecionar?
 Estratégias*
    “Primeiro pelos Detalhes” X “Primeiro pelo Todo”
    Incerto X Familiar
    Maior Valor X Menor Valor
    “Caminho Feliz” X Situações de Erro


       Não há fórmula mágica!




                 * KOSKELA, 2008
Implementação
 Etapas*
    Faking
    Triangulação
    Implementação Óbvia
 Faking
    Passo mais fácil para o teste
     passar (red  green)
    Ter um momento mais
     concreto
    Comece retornando valores
     hardcoding
                * KOSKELA, 2008
Implementação
 Triangulação  transformar
  código fake em código de
  produção
    Os testes levam à solução
     correta
    Triangular = variar testes com
     novos valores

 Implementação Óbvia
    Após triangulação, o trabalho restante vai parecer óbvio
     ou bem mais natural
Demonstração
                            X LTDA          M SA
  História       História
                    3
     1
                             Mostra 1 em    Tudo em 2
         História             1 semana       semanas
             2



                              Mudança!      Mudança!!!


                                            Talvez não
                             Aceita e não
                                             entregue
                             entrega a 3.
                                              nada!
Demonstração
          X LTDA          M SA
                           Design 
           TDD história
                          programação
                1
                             testes


           Mudança       Mudança 
           refactoring    adeus testes!


           Maior valor    Retrabalho e
             ficou!       muita reza!
Considerações Finais
 Boas práticas
    Qualidade do teste  atômico e enxuto
    Granularidade do código = teste
 Outras aplicações
    Código legado
    Interface gráfica
 Dificuldades
    Trabalho em equipe (coesão alta)
    Cultura (pré-conceito e atitude)
    Conhecimento de padrões
 Curso de TDD

TDD - A Verdadeira Face do Teste

  • 1.
    Aislan Fernandes @aislanfp aislanfp@gmail.com
  • 2.
    Roteiro  Contextos  Conceitos Ferramentas  Técnicas  Demonstração
  • 3.
    Referências  KOSKELA, Lasse.Test Driven: Pratictal TDD and Acceptance TDD for Java Developers. Manning. Greenwich, 2008.  FOWLER, Martin. Refactoring: Improving the Design of Existing Code. Addison-Wesley. 1999.  BECK, Kent. Programação Extrema (XP) Explicada – Acolha as mudanças. Porto Alegre: Bookman, 2004.
  • 4.
    Contexto Maior (Organização) Software Mudanças Custo Escopo Projeto Tempo Qualidade Engenharia de Software
  • 5.
    Contexto Menor (Equipe) “Mudança é uma constante, o problema é falta de habilidade”*  O custo da mudança não é exponencial mas achatado Metodologias Ágeis  Não há aquele código difícil de modificar , acompanhado de medo e da falta de testes para Iterativo e Incremental verificar se houve efeito colateral. XP Scrum PU**  TDD é um ingrediente chave  * BECK, 2004; **LARMAN, Craig.
  • 6.
    Conceito  TDD nãoé desenvolvimento com testes! Regra 10 de Myers Quanto mais cedo defeito descoberto menor custo de correção
  • 7.
    Conceito  TDD =fazer certo  TDD = Test-code-refactor  TDD = Red-green-refactor  TDD = Test Driven Development  TDD = Test Driven Design  TDD = Test-First Programming “Infectado por Testes”* = não codificar sem teste antes Acceptance TDD (ATDD) = fazer a coisa certa ≈ BDD * Erich Gamma
  • 8.
    Objetivos*  Benefícios Encorajar um bom design Testes  Produzir código testável  Evitar engenharia excessiva ou pesada Revelar falhas  Evitar código mal escrito, difícil de entender e de mudar Mostrar que faz o que deve  Cortar o tempo em tarefas não ser feito produtivas:  Debugging 100% Revelar design  Resolvendo bugs  Entendendo código ilegível Especificar em exemplos Programar e testar ao mesmo tempo é mais rápido do que apenas programar! * KOSKELA, 2008
  • 9.
    Funcionamento  Ciclo TDD Escreva o teste, e somente então escreva o código para passar no teste. Por fim, transforme o design atual num melhor (refactor).  Repetição dos ciclos TDD = design evolucionário  Quando parar?  Ponto de satisfação ≈ conhecimento de padrões de projeto Test Code Refactor “Os testes me dão a chance de pensar sobre o que eu quero independentemente da implementação.”* * BECK, 2004
  • 10.
    Design Evolucionário  Feedbackimediato  design somente evolui quando efetiva e objetivamente o usamos, escrevendo o teste antes*  Escrever teste = decidir sobre design  Focado no presente  menos custoso  Uso de code coverage  gordura?  Priorizado em histórias “Quando você acrescenta mais ao projeto hoje, você aumenta a sobrecarga do sistema. Há mais coisas para testar, entender e explicar”** “Os problemas de hoje já são suficientes”** * KOSKELA, 2008 ** BECK, 2004
  • 11.
    Design Evolucionário  Testar+ Refatorar  Escrever testes antes promove um certo nível de testabilidade, porém é preciso estar consciente de não construir um que funciona agora mas pode explodir em breve * Design Testável Prefira composição em vez Procure isolar e injetar de herança dependências Melhor Melhor testabilidade e Mais código testabilidade, flexibilidade Mais código manutenção e manutenção * KOSKELA, 2008
  • 12.
    Refactoring  Técnica parareestruturar um código existente, alterando sua estrutura interna sem alterar seu comportamento externo*  Disciplinado  Não prevemos e nem nos preparamos para problemas de design antes de ter um em mãos, evitando criar mais problemas  Padronizado  Remoção de código duplicado  Problemas específicos * FOWLER, 1999
  • 13.
    Ferramentas  Frameworks  EasyMock  JUnit  DBUnit  Integração Contínua  Hudson  Análise Estática  EMMA  Code  TeamCity Coverage  Apache Continuum  PMD  Duplicação e padrões
  • 14.
    EasyMock Mocks Fakes  Má Prática  classes vazias como mocks  Foco  preocupação Stubs com teste e não com ambiente ITranslator mockTranslator = createMock(ITranslator.class);  Problemas  erros de Greeting greeting = new Greeting(mockTranslator); expect(mockTranslator.translate("English", compilação nos testes "Hindi", "Hello")).andReturn("Namaste"); quando mudam as replay(mockTranslator); assertEquals("Namaste Paulo", interfaces greeting.sayHello("Hindi", "Paulo")); verify(mockTranslator);
  • 15.
    Integração Contínua  Médioe longo prazo  repositório de testes difíceis de gerenciar individualmente  Não é possível executar todos os testes  Executar suite de testes a cada pequena mudança permite um feedback imediato
  • 16.
    Implementação Decomposição Programação de requisito por intenção  Decomposição de Requisito*  criar uma lista de testes em vez de tarefas  Foco no que é necessário e não no que poderia ser feito  Programação por Intenção*  escrever teste sem código algum, como se o código existisse!  Foco no que necessitamos e não no que temos Teste é algo um pouco mais concreto, mais executável, mais exemplificativo do que o requisito * KOSKELA, 2008
  • 17.
    Implementação  Qual testeselecionar?  Estratégias*  “Primeiro pelos Detalhes” X “Primeiro pelo Todo”  Incerto X Familiar  Maior Valor X Menor Valor  “Caminho Feliz” X Situações de Erro Não há fórmula mágica! * KOSKELA, 2008
  • 18.
    Implementação  Etapas*  Faking  Triangulação  Implementação Óbvia  Faking  Passo mais fácil para o teste passar (red  green)  Ter um momento mais concreto  Comece retornando valores hardcoding * KOSKELA, 2008
  • 19.
    Implementação  Triangulação transformar código fake em código de produção  Os testes levam à solução correta  Triangular = variar testes com novos valores  Implementação Óbvia  Após triangulação, o trabalho restante vai parecer óbvio ou bem mais natural
  • 20.
    Demonstração X LTDA M SA História História 3 1 Mostra 1 em Tudo em 2 História 1 semana semanas 2 Mudança! Mudança!!! Talvez não Aceita e não entregue entrega a 3. nada!
  • 21.
    Demonstração X LTDA M SA Design  TDD história programação 1  testes Mudança  Mudança  refactoring adeus testes! Maior valor Retrabalho e ficou! muita reza!
  • 22.
    Considerações Finais  Boaspráticas  Qualidade do teste  atômico e enxuto  Granularidade do código = teste  Outras aplicações  Código legado  Interface gráfica  Dificuldades  Trabalho em equipe (coesão alta)  Cultura (pré-conceito e atitude)  Conhecimento de padrões  Curso de TDD