E NO SÉTIMO DIA ELE CRIOU TESTES
TDD e o papel de testes no desenvolvimento de aplicações
Rafael [email protected]
Friday, June 25, 2010
⚠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.
Friday, June 25, 2010
A CRIAÇÃO DO MUNDOdo ponto de vista do desenvolvimento de software
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
@OCriador
Friday, June 25, 2010
@OCriador* Adão has joined #earth
* Eva has joined #earthAdão
Eva
Friday, June 25, 2010
@OCriador* Adão has joined #earth
* Eva has joined #earth
Adão: Agora vou apavorar!
Eva: Primeiro post!
Eva: ah droga!
Eva: Olha! uma maçã!
Adão
Eva
Friday, June 25, 2010
@OCriador* Adão has joined #earth
* Eva has joined #earth
Adão: Agora vou apavorar!
Eva: Primeiro post!
Eva: ah droga!
Eva: Olha! uma maçã!
> Eva morde a maçã
OCriador: eu avisei!
Adão
Eva
Friday, June 25, 2010
@OCriador* Adão has joined #earth
* Eva has joined #earth
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 #earth
Adão
Eva
Friday, June 25, 2010
QUEM É RAFAEL DOHMS?
Rafael Dohms é graduado Engenheiro da Computação pelo UniCEUB. Tem 9 anos de experiência no mercado PHP e atualmente ocupa o cargo de Desenvolvedor Sênior e Especialista em PHP na empresa sul-africana SWAT/MIH. É certificado ZCE PHP5.
Grande agitador da comunidade PHP é co-fundador do PHPDF e atual coordenador do PHPSP. Contribui ativamente na área de testes do PHP e é Host do PHPSPCast, o primeiro podcast sobre PHP do Brazil.
Friday, June 25, 2010
TESTESporque você precisa deles, mas ainda não sabe
Sebastian Bergmann
Friday, June 25, 2010
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
Friday, June 25, 2010
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 complicado
Friday, June 25, 2010
CADA SITUAÇÃO, UMA FERRAMENTA
Frontend Backend PHP
Selenium+
PHPUnit PHPUnit PHPT
Friday, June 25, 2010
ESCREVENDO TESTESquando você começar, nunca mais vai parar
skoop @flickr
Friday, June 25, 2010
MANOWARS!
• Sistema de Batalhas
• Garantindo o elemento aleatório
• Ataque: Fixo + Random
• Defesa: Fixo + Random
• Damage: Atk/Def * Random
Friday, June 25, 2010
UMA BATALHA!Mano Gil pronto para combater. > Atk: 10 / Def: 8Mano Brown pronto para combater. > Atk: 11 / Def: 9Round 1Fight!Gil took 3 damage from BrownGil did 13 damage on BrownGil did 10 damage on BrownGil did 1 damage on BrownGil took 12 damage from BrownGil did 13 damage on BrownGil did 2 damage on BrownGil did 0 damage on BrownGil took 7 damage from BrownGil did 13 damage on BrownGil did 10 damage on BrownGil did 0 damage on BrownGil took 13 damage from BrownGil took 1 damage from BrownGil took 10 damage from BrownGil took 10 damage from BrownGil did 14 damage on BrownGil took 9 damage from BrownGil took 7 damage from BrownGil did 6 damage on BrownGil did 8 damage on BrownGil did 2 damage on BrownGil did 12 damage on BrownGil won!
Friday, June 25, 2010
MW_MANOVamos ver de perto o código
Friday, June 25, 2010
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 = Def
Friday, June 25, 2010
RAIO-X DE UMA SUITE DE TESTES
AllTests
PHPUnit_Framework_TestSuite
Friday, June 25, 2010
RAIO-X DE UMA SUITE DE TESTES
AllTests
PHPUnit_Framework_TestSuite
ClassXTest
PHPUnit_Framework_TestCase
ClassXTest
PHPUnit_Framework_TestCase
ClassXTest
PHPUnit_Framework_TestCase
Friday, June 25, 2010
RAIO-X DE UMA SUITE DE TESTES
AllTests
PHPUnit_Framework_TestSuite
ClassXTest
PHPUnit_Framework_TestCase
ClassXTest
PHPUnit_Framework_TestCase
ClassXTest
PHPUnit_Framework_TestCase
testX
testY
...testX
testY
...testX
testY
...
Friday, June 25, 2010
RAIO-X DE UMA SUITE DE TESTES
AllTests
PHPUnit_Framework_TestSuite
ClassXTest
PHPUnit_Framework_TestCase
ClassXTest
PHPUnit_Framework_TestCase
ClassXTest
PHPUnit_Framework_TestCase
SetUp
TearDown
SetUp
TearDown
SetUp
TearDown
SetUp
TearDown
testX
testY
...testX
testY
...testX
testY
...
Friday, June 25, 2010
EXECUÇÃO DA SUITESetUp
TearDown
SetUp
TearDown
SetUp
TearDown
SetUp
TearDown
Para cada teste
Para cada teste
Para cada teste
Friday, June 25, 2010
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
Friday, June 25, 2010
ESQUADRÃO LIMPEZALimpe 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); }
Friday, June 25, 2010
ESQUADRÃO LIMPEZALimpe tudo o que seu teste criar!
Everything must be clean!
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); }
Friday, June 25, 2010
ESQUADRÃO LIMPEZALimpe tudo o que seu teste criar!
Everything must be clean!
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); }
Arquivos, Banco de Dados, etc...
Friday, June 25, 2010
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ção
Friday, June 25, 2010
TESTANDO OS BÁSICOS
• Estrutura da Suite
• AllTests.php
• MW_Mano
• Testes do 1 ao 6
Friday, June 25, 2010
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=new
Friday, June 25, 2010
CÓDIGO DEINTESTÁVEL
• Singletons
•MyClass::getInstance();
• Dependências
• SO: exec(‘ls -la’);
• Recursos externos: APIs, File System
• Métodos Privados
•private method fazTudo(){...}
Friday, June 25, 2010
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'));}
Friday, June 25, 2010
NINJA TESTING
• Porque, às vezes, os testes precisam de dublês
• Dummy
• Fake
• Stub
• Spy
• Mock
Friday, June 25, 2010
RANDOM SEM O RANDOMpublic 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());}
Friday, June 25, 2010
DATA PROVIDERS
• 1 teste, muitos dados
• Análise completa de diferentes quadros
Friday, June 25, 2010
CODE COVERAGE• 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>
Friday, June 25, 2010
Friday, June 25, 2010
TDDNão é sobre testes, é sobre especificações
Test Driven Development
Friday, June 25, 2010
“TDD é uma forma de projetar software, não apenas uma forma de testar software.”
Sebastian Bergmann - criador do PHPUnit
“It's 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 TDD
Friday, June 25, 2010
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 validar
Friday, June 25, 2010
CICLO DE DESENVOLVIMENTOsem TDD
Especificação Análise Codificação
TestesDeployManutenção
Friday, June 25, 2010
Codificação
Friday, June 25, 2010
Codificação
Friday, June 25, 2010
Codificação
Friday, June 25, 2010
Codificação
Friday, June 25, 2010
Codificação
Friday, June 25, 2010
Codificação
Friday, June 25, 2010
Codificação
Friday, June 25, 2010
Codificação
Friday, June 25, 2010
CICLO DE DESENVOLVIMENTOsem TDD
Especificação Análise Codificação
TestesDeployManutenção
Friday, June 25, 2010
CICLO DE DESENVOLVIMENTOsem TDD
Especificação Análise
Codificação
Testes
DeployManutenção
Friday, June 25, 2010
CICLO DE DESENVOLVIMENTOsem TDD
Especificação Análise
Codificação
Testes
DeployManutenção
Friday, June 25, 2010
Codificação
Testes
O que desejamos que <método> faça?
Como <método> fará o que precisa?
Massa de dados para Teste
Sem formulários, teste direto o backend com os dados
Friday, June 25, 2010
CICLO DE DESENVOLVIMENTOsem com TDD
Especificação Análise
DeployManutenção Codificação
Testes
Friday, June 25, 2010
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 passou
Friday, June 25, 2010
RINSE AND REPEATAutomatize seus testes e garanta qualidade da equipe
Friday, June 25, 2010
CONTINUOS INTEGRATION
• “Integração contínua”
• Processo automatizado
• Executado após cada commit
• Identifica falhas
• Identifica culpados
• Controla qualidade
Friday, June 25, 2010
Friday, June 25, 2010
FERRAMENTAS• phpUnderControl
• baseado no CruiseControl
• Versão atual já formata:
• Resultados de Testes
• PHP Code Sniffer
• Code Coverage
• phpDoc
• Hudson
• Resultados de Testes
• PHP Code Sniffer
• Code Coverage
• phpDoc
• Arbit
• PHP!
• Integração Contínua
• Bug Tracker
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
Friday, June 25, 2010
DÚVIDAS?
Friday, June 25, 2010
Avalie essa palestra: http://joind.in/1705
Obrigado!
Friday, June 25, 2010
Recommended