Qualidade de Software
com TDD e PHPUnit
        Domingos Teruel
              Desenvolvedor
      São José, 21 de agosto de 2011
O Palestrante
✦   Tecnólogo em Computação especialista em Sistemas Web e
    Interface
✦   Atua na área de desenvolvimento e implementação de projetos de
    Software Web
✦   Desenvolvedor Mobile
✦   Desenvolvedor PHP desde 1999 e membro ativo desde 2001
✦   Desenvolvedor WordPress
✦   Membro ativo das comunidades de SL: PHP-SP, PHP-SC, ZF-BR,
    KDE-BR, OpenSUSE-BR, AMAROK-DE e WP-DEVEL
✦   Trocou São Paulo por Floripa para desenvolver seu trabalho na
    Primesoft Sistemas
✦   Na rede: http://about.me/mingomax
A Audiência
✓ Estudantes?
✓ Curiosos / Entusiastas?
✓ Desenvolvedores PHP?
✓ Desenvolvedores de outras linguagens?
✓ Todas as opções acima!
✓ Nenhuma da Opções acima!
Agenda

• Contextualização
• TDD
• Teste Unitários
• PHPUnit
Reflexão
• Errar é inerente a natureza humana.
  Precaver-se contra os erros é uma atitude
  inteligente.

• O processo de desenvolvimento de software
  é sujeito a erros. Sendo assim, a atividade de
  teste é fundamental para se obter produtos
  de software com garantia de qualidade.

• Discordar ou ignorar a frase acima revela
  grande amadorismo.
Qualidade de Software

“Totalidade de características de uma entidade que lhe confere
    a capacidade de satisfazer as necessidades explícitas e
                           implícitas.”
• Conformidade a:
 • Requisitos funcionais e de desempenho;
 • Padrões e convenções de
    desenvolvimento preestabelecidos;

 • Atributos implícitos que todo software
    desenvolvido profissionalmente deve
    possuir.
Como garantir a
qualidade de software?
• Aplicação de métodos e ferramentas
  técnicas;
• Realização de revisões técnicas e inspeções;
• Atividades de testes;
• Aplicação de padrões;
Por quê surgem as
          falhas?

• Alterações;
• Tempo;
• Complexidade;
TESTES
Porque você precisa dele, mas
        ainda não sabe
Prós
•   “Simulação”

       •   Facilidade de testar funções sem precisar preencher
           formulários, criar usuários

       •   Tudo fica centralizado no teste e é feito apenas uma vez

•   “Certeza”

       •   Testes podem simular todas situações possíveis e
           garantir que seu código funciona como esperado

•   “Garantia”

       •   Com um sistema coberto de testes você tem certeza
           que sua alteração não vai quebrar outra área do sistema
Contras
• Tempo
  •   Embora você gaste mais tempo criando
      testes, você ganha tempo durante as
      simulações e na manutenção

• Gerência
  •   Convencer os responsáveis pelo projeto de
      que testes irão trazer lucro é geralmente
      complicado
O que são testes?
“ O teste consiste em executar o
  programa com a intenção de
encontrar erros”. (Myers, 1979)
• Principais objetivos dos testes:
     • Foco na prevenção de erros;
     • Descobrir sintomas causados por
       erros;

     • Fornecer diagnósticos claros para
       que os erros sejam facilmente
       corrigidos;
Teste versus
 Depuração
Objetivo do teste: mostrar que o software tem
erros.




Objetivos da depuração: encontrar a causa do
erro detectado no teste, e projetar e implementar as
modificações no programa para correção do erro
Tipos de testes
• Testes de Unidade;
• Testes de Integração;
• Testes de Sistema;
• Testes de Integração de Sistema;
• Testes de Aceitação;
A “Espiral da Morte” do Teste
Test Driven
Development, TDD
“TDD = Test-
First + Design
 Incremental”
    Kent Beck
•   TDD é uma técnica de desenvolvimento de software
    cujo processo é formado por pequenas iterações para o
    desenvolvimento de uma nova funcionalidade,
    começando pela implementação de um caso de teste,
    depois pelo código necessário para fazer o teste passar,
    e finalmente pela refatoração do código visando melhor
    acomodar as mudanças feitas.

•   Não é um método para testar software, mas para
    construir software.

•   TDD vem do conceito de “test-first programming” do XP
    (Extreme Programming), mas acabou ganhando tanto
    interesse, que hoje tem sido adotado independente do
    XP e das técnicas de programação ágil;
Test-first
• Escrever testes antes da implementação:
   • Faz você pensar no comportamento
   • Reduz código especulativo
   • Documenta
• Escreva somente código suficiente para o
  teste passar e nada além disso

• Escreva testes pequenos: teste a menor
  quantidade possível de código de cada vez

• Escreva testes muito rápidos: não devem
  demorar mais do que alguns segundos para
  serem executados
Design incremtal
• Adição de novas funcionalidades em
  pequenos passos

• O conceito chave de TDD é ter um
  feedback rápido das mudanças no código
• A Metodologia TDD é conduzida através
  dos “testes do programador”.

• Frequentemente esses testes são chamados
  de “teste de unidade”, mas esse nem
  sempre é o caso (pode ser teste de
  integração).

• É importante destacar que não se trata dos
  testes de sistema (caixa preta) nem os de
  aceitação (feitos pelo usuário final)
MANTRA
  DO
 TDD
Ainda sobre tipo de
       testes
Testes Unitários
• Testam apenas um componente do sistema
• Todos os outros componentes são
  simulados (mock objects)

• Ferramenta: PHPUnit
• Fundamental para a prática do
  TDD!
Testes de Integração
• Testam a integração entre componentes
• Envolvem dois ou mais componentes
  (classes+SGBD, classes+SGBD+Fast, etc.)

• Ferramenta: PHPUnit, DBUnit, HSQLDB, Fit
• Normalmente não utilizado em TDD
Testes de Aceitação
• Testam uma história, funcionalidade ou caso
  de uso

• Envolvem vários componentes do sistema
• Ferramenta
: PHPUnit, Selenium
• Pode ser utilizado em TDD
Teste Unitário e
    PHPUnit
Atitude!

• Testar é uma atividade destrutiva!
• Pense de forma negativa quando estiver
  criando planos de teste ou explorando o
  software!
• Explore funcionalidades, pense no que não
  foi pensado!
Princípios
•   São independentes:
     •   Do código já testado;
     •   Da ordem de execução;
     •   Do ambiente;


•   Devem ser:
     •   Fáceis de escrever;
     •   Fáceis de executar;
     •   Fáceis de compreender;
     •   Desenvolvidos paralelamente ao código;
PHPUnit
•   Escrito por Sebastian
    Bergmann

•   Baseado nos conceitos
    do JUnit

•   Atualmente na versão
    3.6.12

•   Requer PHP 5
Escrevendo testes
Quando você começar, nunca mais vai parar
Anatomia
•   Toda classe deve ter seu par para Teste:
     •   nomeClasse.php
     •   <nomeClasse>Test.php


•   Escrever o caso de teste, usando o pós-fixo “Test”
     •   A classe tem um metodo algumaCoisa()
     •   Deve-se criar um metodo testAlgumaCoisa()
Anatomia de um teste
      unitário
Raio-x Suite de Testes
Executando
Isolamento
•   Mantenha seus testes isolados

•   Nunca rode testes no servidor de produção!
•   Soluções
     •   Crie uma base separada
     •   Use pastas separadas para arquivos

     •   Sempre destrua tudo que seu teste
         construiu
Mantenha seu ambiente
       limpo!
O que não se pode
     testar?
•   Singletons

        •   MinhaClasse::getInstance();

•   Depêndencias

        •   SO exec('ls -la')

        •   Recursos externos: APIs, Filesystem

•   Métodos privados

    •   private method fazTudo() {...
Outros recursos
 interessantes
As vezes os testes
  precisam de dublês
• Dummy
• Fake
• Stub
• Spy
• Mock
•   Gera resultados não determinísticos (hora, temperatura
    atual...);

•   Tem estados que são difíceis de criar ou reproduzir
    (erro de
    comunicação da rede);

•   É lento (um banco de dados completo que precisa ser
    inicializado antes do teste);

•   Ainda não existe ou pode ter comportamento alterado;

•   Teriam que adicionar informações e métodos
    exclusivamente para os testes (e não para sua função
    real).
Conclusões
• Colabora para o aumento da qualidade dos
  sistemas

• Desenvolvedores ficam mais corajosos e
  confiantes ao programar!

• Software cresce de forma ordenada e com
  qualidade de design

• Software se adapta com mais facilidade a
  mudanças
•   Demora mais?

    •   No início é necessário escrever muitos testes

    •   Depois da inércia a suite de regressão está pronta e
        escrevem-se menos testes

    •   Certeza de que a implementação está funcionando

    •   Maioria dos bugs encontrados em tempo de
        desenvolvimento

    •   Bugs de produção são encontrados e corrigidos com muito
        mais velocidade

•   Então no fim das contas demora-se muito menos tempo e com
    muito mais qualidade!
Referências
•   Introduction to TDD: http://www.agiledata.org/essays/tdd.html

•   Desenvolvimento Orientado a Testes: http://www.improveit.com.br/xp/
    praticas/tdd

•   Screencast TDD em ação: http://dojofloripa.wordpress.com/2007/05/21/
    screencast-tdd-em- acao/

•   Improve your unit tests by replacing your collaborators with mock
    objects: http://www.opensourcetutorials.com/tutorials/Server-Side-
    Coding/Java/java-unit-testing-with-mock-objects

•   Behaviour-Driven Development: http://behaviour-driven.org/

•   Test-drivendevelopment: by example [KentBeck]

•   Growing Object-Oriented Software,Guided byTests [Steve Freeman]

•   PHPUnit Pocket guide [Sebastian Bergmann]
Perguntas
Obrigado!!!!!
Feedbacks: http://joind.in/event/view/779

Qualidade no desenvolvimento de Software com TDD e PHPUnit

  • 1.
    Qualidade de Software comTDD e PHPUnit Domingos Teruel Desenvolvedor São José, 21 de agosto de 2011
  • 2.
    O Palestrante ✦ Tecnólogo em Computação especialista em Sistemas Web e Interface ✦ Atua na área de desenvolvimento e implementação de projetos de Software Web ✦ Desenvolvedor Mobile ✦ Desenvolvedor PHP desde 1999 e membro ativo desde 2001 ✦ Desenvolvedor WordPress ✦ Membro ativo das comunidades de SL: PHP-SP, PHP-SC, ZF-BR, KDE-BR, OpenSUSE-BR, AMAROK-DE e WP-DEVEL ✦ Trocou São Paulo por Floripa para desenvolver seu trabalho na Primesoft Sistemas ✦ Na rede: http://about.me/mingomax
  • 3.
    A Audiência ✓ Estudantes? ✓Curiosos / Entusiastas? ✓ Desenvolvedores PHP? ✓ Desenvolvedores de outras linguagens? ✓ Todas as opções acima! ✓ Nenhuma da Opções acima!
  • 4.
    Agenda • Contextualização • TDD •Teste Unitários • PHPUnit
  • 5.
  • 6.
    • Errar éinerente a natureza humana. Precaver-se contra os erros é uma atitude inteligente. • O processo de desenvolvimento de software é sujeito a erros. Sendo assim, a atividade de teste é fundamental para se obter produtos de software com garantia de qualidade. • Discordar ou ignorar a frase acima revela grande amadorismo.
  • 7.
    Qualidade de Software “Totalidadede características de uma entidade que lhe confere a capacidade de satisfazer as necessidades explícitas e implícitas.”
  • 8.
    • Conformidade a: • Requisitos funcionais e de desempenho; • Padrões e convenções de desenvolvimento preestabelecidos; • Atributos implícitos que todo software desenvolvido profissionalmente deve possuir.
  • 9.
    Como garantir a qualidadede software? • Aplicação de métodos e ferramentas técnicas; • Realização de revisões técnicas e inspeções; • Atividades de testes; • Aplicação de padrões;
  • 10.
    Por quê surgemas falhas? • Alterações; • Tempo; • Complexidade;
  • 11.
    TESTES Porque você precisadele, mas ainda não sabe
  • 12.
  • 13.
    “Simulação” • Facilidade de testar funções sem precisar preencher formulários, criar usuários • Tudo fica centralizado no teste e é feito apenas uma vez • “Certeza” • Testes podem simular todas situações possíveis e garantir que seu código funciona como esperado • “Garantia” • Com um sistema coberto de testes você tem certeza que sua alteração não vai quebrar outra área do sistema
  • 14.
  • 15.
    • Tempo • Embora você gaste mais tempo criando testes, você ganha tempo durante as simulações e na manutenção • Gerência • Convencer os responsáveis pelo projeto de que testes irão trazer lucro é geralmente complicado
  • 16.
    O que sãotestes?
  • 17.
    “ O testeconsiste em executar o programa com a intenção de encontrar erros”. (Myers, 1979)
  • 18.
    • Principais objetivosdos testes: • Foco na prevenção de erros; • Descobrir sintomas causados por erros; • Fornecer diagnósticos claros para que os erros sejam facilmente corrigidos;
  • 19.
  • 20.
    Objetivo do teste:mostrar que o software tem erros. Objetivos da depuração: encontrar a causa do erro detectado no teste, e projetar e implementar as modificações no programa para correção do erro
  • 21.
  • 22.
    • Testes deUnidade; • Testes de Integração; • Testes de Sistema; • Testes de Integração de Sistema; • Testes de Aceitação;
  • 23.
    A “Espiral daMorte” do Teste
  • 24.
  • 25.
    “TDD = Test- First+ Design Incremental” Kent Beck
  • 26.
    TDD é uma técnica de desenvolvimento de software cujo processo é formado por pequenas iterações para o desenvolvimento de uma nova funcionalidade, começando pela implementação de um caso de teste, depois pelo código necessário para fazer o teste passar, e finalmente pela refatoração do código visando melhor acomodar as mudanças feitas. • Não é um método para testar software, mas para construir software. • TDD vem do conceito de “test-first programming” do XP (Extreme Programming), mas acabou ganhando tanto interesse, que hoje tem sido adotado independente do XP e das técnicas de programação ágil;
  • 27.
  • 28.
    • Escrever testesantes da implementação: • Faz você pensar no comportamento • Reduz código especulativo • Documenta
  • 29.
    • Escreva somentecódigo suficiente para o teste passar e nada além disso • Escreva testes pequenos: teste a menor quantidade possível de código de cada vez • Escreva testes muito rápidos: não devem demorar mais do que alguns segundos para serem executados
  • 30.
  • 31.
    • Adição denovas funcionalidades em pequenos passos • O conceito chave de TDD é ter um feedback rápido das mudanças no código
  • 32.
    • A MetodologiaTDD é conduzida através dos “testes do programador”. • Frequentemente esses testes são chamados de “teste de unidade”, mas esse nem sempre é o caso (pode ser teste de integração). • É importante destacar que não se trata dos testes de sistema (caixa preta) nem os de aceitação (feitos pelo usuário final)
  • 33.
  • 34.
  • 35.
  • 36.
    • Testam apenasum componente do sistema • Todos os outros componentes são simulados (mock objects) • Ferramenta: PHPUnit • Fundamental para a prática do TDD!
  • 37.
  • 38.
    • Testam aintegração entre componentes • Envolvem dois ou mais componentes (classes+SGBD, classes+SGBD+Fast, etc.) • Ferramenta: PHPUnit, DBUnit, HSQLDB, Fit • Normalmente não utilizado em TDD
  • 39.
  • 40.
    • Testam umahistória, funcionalidade ou caso de uso • Envolvem vários componentes do sistema • Ferramenta : PHPUnit, Selenium • Pode ser utilizado em TDD
  • 41.
  • 42.
    Atitude! • Testar éuma atividade destrutiva! • Pense de forma negativa quando estiver criando planos de teste ou explorando o software! • Explore funcionalidades, pense no que não foi pensado!
  • 43.
    Princípios • São independentes: • Do código já testado; • Da ordem de execução; • Do ambiente; • Devem ser: • Fáceis de escrever; • Fáceis de executar; • Fáceis de compreender; • Desenvolvidos paralelamente ao código;
  • 44.
    PHPUnit • Escrito por Sebastian Bergmann • Baseado nos conceitos do JUnit • Atualmente na versão 3.6.12 • Requer PHP 5
  • 45.
    Escrevendo testes Quando vocêcomeçar, nunca mais vai parar
  • 46.
    Anatomia • Toda classe deve ter seu par para Teste: • nomeClasse.php • <nomeClasse>Test.php • Escrever o caso de teste, usando o pós-fixo “Test” • A classe tem um metodo algumaCoisa() • Deve-se criar um metodo testAlgumaCoisa()
  • 47.
    Anatomia de umteste unitário
  • 48.
  • 49.
  • 50.
    Isolamento • Mantenha seus testes isolados • Nunca rode testes no servidor de produção! • Soluções • Crie uma base separada • Use pastas separadas para arquivos • Sempre destrua tudo que seu teste construiu
  • 51.
  • 52.
    O que nãose pode testar?
  • 53.
    Singletons • MinhaClasse::getInstance(); • Depêndencias • SO exec('ls -la') • Recursos externos: APIs, Filesystem • Métodos privados • private method fazTudo() {...
  • 54.
  • 55.
    As vezes ostestes precisam de dublês • Dummy • Fake • Stub • Spy • Mock
  • 56.
    Gera resultados não determinísticos (hora, temperatura atual...); • Tem estados que são difíceis de criar ou reproduzir (erro de comunicação da rede); • É lento (um banco de dados completo que precisa ser inicializado antes do teste); • Ainda não existe ou pode ter comportamento alterado; • Teriam que adicionar informações e métodos exclusivamente para os testes (e não para sua função real).
  • 57.
  • 58.
    • Colabora parao aumento da qualidade dos sistemas • Desenvolvedores ficam mais corajosos e confiantes ao programar! • Software cresce de forma ordenada e com qualidade de design • Software se adapta com mais facilidade a mudanças
  • 59.
    Demora mais? • No início é necessário escrever muitos testes • Depois da inércia a suite de regressão está pronta e escrevem-se menos testes • Certeza de que a implementação está funcionando • Maioria dos bugs encontrados em tempo de desenvolvimento • Bugs de produção são encontrados e corrigidos com muito mais velocidade • Então no fim das contas demora-se muito menos tempo e com muito mais qualidade!
  • 60.
  • 61.
    Introduction to TDD: http://www.agiledata.org/essays/tdd.html • Desenvolvimento Orientado a Testes: http://www.improveit.com.br/xp/ praticas/tdd • Screencast TDD em ação: http://dojofloripa.wordpress.com/2007/05/21/ screencast-tdd-em- acao/ • Improve your unit tests by replacing your collaborators with mock objects: http://www.opensourcetutorials.com/tutorials/Server-Side- Coding/Java/java-unit-testing-with-mock-objects • Behaviour-Driven Development: http://behaviour-driven.org/ • Test-drivendevelopment: by example [KentBeck] • Growing Object-Oriented Software,Guided byTests [Steve Freeman] • PHPUnit Pocket guide [Sebastian Bergmann]
  • 62.
  • 63.