TDC 2011 - E no sétimo dia ele escreveu testes

  • 2,267 views
Uploaded on

Testes e o TDD estão se tornando uma parte muito importante do nosso dia a dia como desenvolvedores. Veja como os testes se aplicam ao seu trabalho e como seus sistemas e equipe podem se beneficiar …

Testes e o TDD estão se tornando uma parte muito importante do nosso dia a dia como desenvolvedores. Veja como os testes se aplicam ao seu trabalho e como seus sistemas e equipe podem se beneficiar com isso. Aprenda também o que é o TDD e quais melhorias ele traz ao processo de desenvolvimento.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,267
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
28
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. E NO SÉTIMO DIA ELE CRIOU TESTES TDD e o papel de testes no desenvolvimento de aplicações Rafael Dohms rafael@rafaeldohms.com.brSaturday, July 9, 2011
  • 2. Aviso As referências e opiniões religiosas apresentadas nesta palestra não refletem a opinião do autor, e são apresentadas puramente com intuito de ilustrar pontos-chave de forma descontraída e humorística.Saturday, July 9, 2011
  • 3. A CRIAÇÃO DO MUNDO do ponto de vista do desenvolvimento de softwareSaturday, July 9, 2011
  • 4. Saturday, July 9, 2011
  • 5. Saturday, July 9, 2011
  • 6. Saturday, July 9, 2011
  • 7. Saturday, July 9, 2011
  • 8. Saturday, July 9, 2011
  • 9. Saturday, July 9, 2011
  • 10. Saturday, July 9, 2011
  • 11. Saturday, July 9, 2011
  • 12. @OCriadorSaturday, July 9, 2011
  • 13. @OCriador * Adão has joined #earth Adão * Eva has joined #earth EvaSaturday, July 9, 2011
  • 14. @OCriador * Adão has joined #earth Adão * Eva has joined #earth Eva Adão: Agora vou apavorar! Eva: Primeiro post! Eva: ah droga! Eva: Olha! uma maçã!Saturday, July 9, 2011
  • 15. @OCriador * Adão has joined #earth Adão * Eva has joined #earth Eva Adão: Agora vou apavorar! Eva: Primeiro post! Eva: ah droga! Eva: Olha! uma maçã! > Eva morde a maçã OCriador: eu avisei!Saturday, July 9, 2011
  • 16. @OCriador * Adão has joined #earth Adão * Eva has joined #earth Eva Adão: Agora vou apavorar! Eva: Primeiro post! Eva: ah droga! Eva: Olha! uma maçã! > Eva morde a maçã OCriador: eu avisei! OCriador kicks Eva OCriador kicks Adão OCriador adds ban on *@earth on #earthSaturday, July 9, 2011
  • 17. Rafael Dohms photo credit: Eli White Evangelista PHP, membro ativo da Comunidade PHP e certificado ZCE. Ele ajudou na fundação de dois Grupos de Usuários de PHP ao longo do tempo e hoje compartilha a coordenação do PHPSP. Desenvolvedor, gamer e apaixonado por código ele também é host do primeiro podcast de PHP do Brasil: PHPSPCast. Atualmente ele trabalha na equipe SWAT do grupo MIH, uma equipe de experts que fornecem conhecimento técnico para o grupo além de trabalhar com P&D buscando novos nichos da internet e tecnologia. Seu papel como Desenvolvedor Sênior é codar, treinar e auxiliar outras empresas e se divertir enquanto faz isso.Saturday, July 9, 2011
  • 18. Sebastian Bergmann TESTES porque você precisa deles, mas ainda não sabeSaturday, July 9, 2011
  • 19. TESTES? • Descrever programaticamente um caso de uso válido e garantir sua funcionalidade • Forçar a execução de seu código em diversos cenários • Objetivos • Garantir funcionamento • Agilizar a refatoração • Testes automatizadosSaturday, July 9, 2011
  • 20. TIPOS • Teste Unitário • Pequeno e pontual • Geralmente testa a entrada/saída de uma função • Teste Funcional • Verifica a funcionalidade de interfaces • End-to-End • Verifica o processo do início ao fim • Analisa o fluxo de sua aplicaçãoSaturday, July 9, 2011
  • 21. 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 sistemaSaturday, July 9, 2011
  • 22. CONS • 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 complicadoSaturday, July 9, 2011
  • 23. CADA SITUAÇÃO, UMA FERRAMENTA Frontend Backend PHP Selenium + PHPUnit PHPT PHPUnitSaturday, July 9, 2011
  • 24. skoop @flickr ESCREVENDO TESTES quando você começar, nunca mais vai pararSaturday, July 9, 2011
  • 25. MANOWARS! • Sistema de Batalhas • Garantindo o elemento aleatório • Ataque: Fixo + Random • Defesa: Fixo + Random • Damage: Atk/Def * RandomSaturday, July 9, 2011
  • 26. Mano Gil pronto para combater. > Atk: 10 / Def: 8 Mano Brown pronto para combater. > Atk: 11 / Def: 9 UMA BATALHA! Round 1 Fight! Gil took 3 damage from Brown Gil did 13 damage on Brown Gil did 10 damage on Brown Gil did 1 damage on Brown Gil took 12 damage from Brown Gil did 13 damage on Brown Gil did 2 damage on Brown Gil did 0 damage on Brown Gil took 7 damage from Brown Gil did 13 damage on Brown Gil did 10 damage on Brown Gil did 0 damage on Brown Gil took 13 damage from Brown Gil took 1 damage from Brown Gil took 10 damage from Brown Gil took 10 damage from Brown Gil did 14 damage on Brown Gil took 9 damage from Brown Gil took 7 damage from Brown Gil did 6 damage on Brown Gil did 8 damage on Brown Gil did 2 damage on Brown Gil did 12 damage on Brown Gil won!Saturday, July 9, 2011
  • 27. MW_MANO Vamos ver de perto o códigoSaturday, July 9, 2011
  • 28. O QUE TESTAR? 1.O construtor esta definindo as variáveis? 2.O health (saúde) está em 100 quando damos reset? 3.Quando ele se machuca, o health diminui? 4.Quando vivo, ele diz “tô vivo”? 5.Quando morto, ele morre? 6.Ele se defende com o valor de defesa esperado? 7.Ele ganha bonus de defesa? 8.Qual o resultado de um ataque (sem bônus), quando: 8.1.Atk > Def 8.2.Def > Atk 8.3.Atk = DefSaturday, July 9, 2011
  • 29. RAIO-X DE UMA SUITE DE TESTES PHPUnit_Framework_TestSuite AllTestsSaturday, July 9, 2011
  • 30. RAIO-X DE UMA SUITE DE TESTES PHPUnit_Framework_TestSuite AllTests PHPUnit_Framework_TestCase ClassXTest PHPUnit_Framework_TestCase ClassXTest PHPUnit_Framework_TestCase ClassXTestSaturday, July 9, 2011
  • 31. RAIO-X DE UMA SUITE DE TESTES PHPUnit_Framework_TestSuite AllTests PHPUnit_Framework_TestCase testX ClassXTest ... testY PHPUnit_Framework_TestCase testX ClassXTest ... testY PHPUnit_Framework_TestCase testX ClassXTest ... testYSaturday, July 9, 2011
  • 32. RAIO-X DE UMA SUITE DE TESTES PHPUnit_Framework_TestSuite SetUp AllTests TearDown PHPUnit_Framework_TestCase SetUp testX ClassXTest ... TearDown testY PHPUnit_Framework_TestCase SetUp testX ClassXTest ... TearDown testY PHPUnit_Framework_TestCase SetUp testX ClassXTest ... TearDown testYSaturday, July 9, 2011
  • 33. EXECUÇÃO DA SUITE SetUp SetUp Para cada teste TearDown SetUp Para cada teste TearDown SetUp Para cada teste TearDown TearDownSaturday, July 9, 2011
  • 34. 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 construiuSaturday, July 9, 2011
  • 35. ESQUADRÃO LIMPEZA Limpe tudo o que seu teste criar! class CleanUpTest extends PHPUnit_Framework_TestCase { private $file = "/tmp/file"; protected function setUp() { parent::setUp(); } protected function tearDown() { unlink($this->file); parent::tearDown(); } public function testFile() { file_put_contents($this->file); }Saturday, July 9, 2011
  • 36. ESQUADRÃO LIMPEZA Limpe tudo o que seu teste criar! class CleanUpTest extends PHPUnit_Framework_TestCase { private $file = "/tmp/file"; protected function setUp() { parent::setUp(); } protected function tearDown() { unlink($this->file); parent::tearDown(); } public function testFile() Everything { must be clean! file_put_contents($this->file); }Saturday, July 9, 2011
  • 37. ESQUADRÃO LIMPEZA Limpe tudo o que seu teste criar! class CleanUpTest extends PHPUnit_Framework_TestCase { private $file = "/tmp/file"; protected function setUp() { parent::setUp(); } protected function tearDown() { Arquivos, Banco de unlink($this->file); Dados, etc... parent::tearDown(); } public function testFile() Everything { must be clean! file_put_contents($this->file); }Saturday, July 9, 2011
  • 38. QUANDO LIMPAR? class CleanUpTest extends PHPUnit_Framework_TestCase { private $file = "/tmp/file"; protected function setUp() { parent::setUp(); } protected function tearDown() { parent::tearDown(); } public function testFile() { file_put_contents($this->file); $this->assertSomething(...); unlink($this->file); }Saturday, July 9, 2011
  • 39. QUANDO LIMPAR? class CleanUpTest extends PHPUnit_Framework_TestCase { private $file = "/tmp/file"; protected function setUp() { parent::setUp(); } protected function tearDown() { parent::tearDown(); } public function testFile() { file_put_contents($this->file); $this->assertSomething(...); Interrompe o unlink($this->file); teste se falhar }Saturday, July 9, 2011
  • 40. TESTANDO OS BÁSICOS • Estrutura da Suite • AllTests.php • MW_Mano • Testes do 1 ao 6Saturday, July 9, 2011
  • 41. public function attack(MW_Mano $victim) { $atk = $this->getAtk() + trim(file_get_contents(URL)); $def = $victim->defend(); $dmgMultiplier = (trim(file_get_contents(URL)))/100; if ($atk > $def){ $dmg = round($atk * $dmgMultiplier); $victim->hurt( $dmg ); $action = "%s did %d damage on %s"; }else{ $dmg = round($def * $dmgMultiplier); $this->hurt( $dmg ); $action = "%s took %d damage from %s"; } return sprintf($action, $this->getName(), $dmg, $victim->getName()); } Para Facilitar leitura: [URL] => http://www.random.org/integers/?num=1&min=0&max=100&col=1&base=10&format=plain&rnd=newSaturday, July 9, 2011
  • 42. CÓDIGO DEINTESTÁVEL • Singletons • MyClass::getInstance(); • Dependências • SO: exec(‘ls -la’); • Recursos externos: APIs, File System • Métodos Privados • private method fazTudo(){...}Saturday, July 9, 2011
  • 43. public function attack(MW_Mano $victim) { $atk = $this->getAtk() + $this->getRandom(); $def = $victim->defend(); $dmgMultiplier = $this->getRandom(1,100)/100; if ($atk > $def){ $dmg = round($atk * $dmgMultiplier); $victim->hurt( $dmg ); $action = "%s did %d damage on %s"; }else{ $dmg = round($def * $dmgMultiplier); $this->hurt( $dmg ); $action = "%s took %d damage from %s"; } return sprintf($action, $this->getName(), $dmg, $victim->getName()); } public function getRandom($min = 1, $max = 10) { return trim(file_get_contents(http://www.random.org/integers/?num=1&min=. $min.&max=.$max.&col=1&base=10&format=plain&rnd=new)); }Saturday, July 9, 2011
  • 44. public function attack(MW_Mano $victim) { $atk = $this->getAtk() + $this->getRandom(); $def = $victim->defend(); $dmgMultiplier = $this->getRandom(1,100)/100; if ($atk > $def){ $dmg = round($atk * $dmgMultiplier); $victim->hurt( $dmg ); $action = "%s did %d damage on %s"; }else{ $dmg = round($def * $dmgMultiplier); $this->hurt( $dmg ); $action = "%s took %d damage from %s"; } return sprintf($action, $this->getName(), $dmg, $victim->getName()); } public function getRandom($min = 1, $max = 10) { return trim(file_get_contents(http://www.random.org/integers/?num=1&min=. $min.&max=.$max.&col=1&base=10&format=plain&rnd=new)); }Saturday, July 9, 2011
  • 45. CENAS ARRISCADAS • Porque, às vezes, os testes precisam de dublês • Removem dependências em código externo • Oferecem controle sobre resultados • Estratégias comuns: • Dummy, Fake, Stub, Spy, MockSaturday, July 9, 2011
  • 46. MOCK OBJECT • Em português: falso, imitação (Objeto falso) • Significa: copiar, imitar ou falsificar • Objetivo: trocar algo que não temos controle por outro do qual podemos garantir o resultado, forçando diferentes cenários.Saturday, July 9, 2011
  • 47. RANDOM SEM O RANDOM public function testDefendWithoutLuck() { //Obter Mock $manoMock = $this->getMock(MW_Mano,array(getRandom), array(John)); //Definir que o objeto retorne zero. $manoMock->expects($this->any()) ->method(getRandom) ->will($this->returnValue(0)); //Definir defesa $manoMock->setDef(5); //Verificar que defesa nao se altera $this->assertEquals(5, $manoMock->defend()); }Saturday, July 9, 2011
  • 48. DATA PROVIDERS • Um teste, muitos dados • Análise completa de diferentes cenáriosSaturday, July 9, 2011
  • 49. CODE COVERAGE Medindo a eficiência de nossos testes • phpunit.xml <phpunit colors="true" verbose="true"> <logging> <log type="coverage-html" target="_reports" charset="UTF-8" yui="true" highlight="true" /> </logging> <filter> <blacklist> <directory suffix=".php">../libs/Zend</directory> </blacklist> <whitelist> <directory suffix=".php">../libs/MW</directory> </whitelist> </filter> </phpunit>Saturday, July 9, 2011
  • 50. Saturday, July 9, 2011
  • 51. Test Driven Development TDD Não é sobre testes, é sobre especificaçõesSaturday, July 9, 2011
  • 52. “TDD é uma forma de projetar software, não apenas uma forma de testar software.” Sebastian Bergmann - criador do PHPUnit “Its about figuring out what you are trying to do before you run off half-cocked to try to do it.” Dave Astels - autor de livros sobre TDDSaturday, July 9, 2011
  • 53. TDD • Escrever testes que definem o comportamento de sua aplicação antes de escrever código. • Testar comportamento, não apenas funcionamento • Especificar e não apenas validarSaturday, July 9, 2011
  • 54. Especificação Análise Codificação Manutenção Deploy Testes CICLO DE DESENVOLVIMENTO sem TDDSaturday, July 9, 2011
  • 55. CodificaçãoSaturday, July 9, 2011
  • 56. CodificaçãoSaturday, July 9, 2011
  • 57. CodificaçãoSaturday, July 9, 2011
  • 58. CodificaçãoSaturday, July 9, 2011
  • 59. CodificaçãoSaturday, July 9, 2011
  • 60. CodificaçãoSaturday, July 9, 2011
  • 61. CodificaçãoSaturday, July 9, 2011
  • 62. CodificaçãoSaturday, July 9, 2011
  • 63. Especificação Análise Codificação Manutenção Deploy Testes CICLO DE DESENVOLVIMENTO sem TDDSaturday, July 9, 2011
  • 64. Especificação Análise Testes Manutenção Deploy Codificação CICLO DE DESENVOLVIMENTO sem TDDSaturday, July 9, 2011
  • 65. Especificação Análise Testes Manutenção Deploy Codificação CICLO DE DESENVOLVIMENTO sem TDDSaturday, July 9, 2011
  • 66. Testes O que desejamos que <método> faça? Quais são os cenários que ele precisa estar preparado para lidar? Codificação Como <método> fará o que precisa? Sem formulários, teste direto o backend com os dadosSaturday, July 9, 2011
  • 67. Especificação Análise Testes Manutenção Deploy Codificação CICLO DE DESENVOLVIMENTO sem com TDDSaturday, July 9, 2011
  • 68. Manutenção • Processo de correção de bugs • Identificar erro • Escrever teste que cause falha • Corrigir código • Rodar teste novamente • Verificar que o teste passouSaturday, July 9, 2011
  • 69. RINSE AND REPEAT Automatize seus testes e garanta qualidade da equipeSaturday, July 9, 2011
  • 70. CONTINUOS INTEGRATION • “Integração contínua” • Processo automatizado • Executado após cada commit • Identifica falhas • Identifica culpados • Controla qualidadeSaturday, July 9, 2011
  • 71. Saturday, July 9, 2011
  • 72. FERRAMENTAS • phpUnderControl • Hudson • baseado no CruiseControl • Resultados de Testes • Versão atual já formata: • PHP Code Sniffer • Resultados de Testes • Code Coverage • PHP Code Sniffer • phpDoc • Code Coverage • Arbit • phpDoc • PHP! • Integração Contínua • Bug TrackerSaturday, July 9, 2011
  • 73. Saturday, July 9, 2011
  • 74. Saturday, July 9, 2011
  • 75. DÚVIDAS?Saturday, July 9, 2011
  • 76. Obrigado! http://doh.ms rafael@doh.ms Slides: http://slides.doh.ms Código: https://github.com/rdohms/ManoWars Avalie essa palestra: http://joind.in/3571Saturday, July 9, 2011