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.
O código fonte utilizado esta no github: http://github.com/rdohms/ManoWars
Palestra ministrada no 5º Seminario PHP.
A Journey into your Lizard Brain - PHP Conference Brasil 2015
E no Sétimo dia ele escreveu testes - Seminario PHP
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.br
Friday, June 25, 2010
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.
Friday, June 25, 2010
3. A CRIAÇÃO DO MUNDO
do ponto de vista do desenvolvimento de software
Friday, June 25, 2010
13. @OCriador
* Adão has joined #earth
Adão
* Eva has joined #earth
Eva
Friday, June 25, 2010
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çã!
Friday, June 25, 2010
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!
Friday, June 25, 2010
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 #earth
Friday, June 25, 2010
17. 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
18. Sebastian
Bergmann
TESTES
porque você precisa deles, mas ainda não sabe
Friday, June 25, 2010
19. 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
20. 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
21. CADA SITUAÇÃO, UMA FERRAMENTA
Frontend Backend PHP
Selenium
+ PHPUnit PHPT
PHPUnit
Friday, June 25, 2010
22. skoop @flickr
ESCREVENDO TESTES
quando você começar, nunca mais vai parar
Friday, June 25, 2010
23. MANOWARS!
• Sistema de Batalhas
• Garantindo o elemento aleatório
• Ataque: Fixo + Random
• Defesa: Fixo + Random
• Damage: Atk/Def * Random
Friday, June 25, 2010
24. 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!
Friday, June 25, 2010
25. MW_MANO
Vamos ver de perto o código
Friday, June 25, 2010
26. 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
27. RAIO-X DE UMA SUITE DE TESTES
PHPUnit_Framework_TestSuite
AllTests
Friday, June 25, 2010
28. RAIO-X DE UMA SUITE DE TESTES
PHPUnit_Framework_TestSuite
AllTests
PHPUnit_Framework_TestCase
ClassXTest
PHPUnit_Framework_TestCase
ClassXTest
PHPUnit_Framework_TestCase
ClassXTest
Friday, June 25, 2010
29. 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
...
testY
Friday, June 25, 2010
30. 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 testY
Friday, June 25, 2010
31. EXECUÇÃO DA SUITE
SetUp
SetUp
Para cada teste
TearDown
SetUp
Para cada teste
TearDown
SetUp
Para cada teste
TearDown
TearDown
Friday, June 25, 2010
32. 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
33. 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);
}
Friday, June 25, 2010
34. 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);
}
Friday, June 25, 2010
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()
{ Arquivos, Banco de
unlink($this->file); Dados, etc...
parent::tearDown();
}
public function testFile() Everything
{ must be clean!
file_put_contents($this->file);
}
Friday, June 25, 2010
36. 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
37. TESTANDO OS BÁSICOS
• Estrutura da Suite
• AllTests.php
• MW_Mano
• Testes do 1 ao 6
Friday, June 25, 2010
38. 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
39. 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
40. 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
41. NINJA TESTING
• Porque, às vezes, os testes precisam de dublês
• Dummy
• Fake
• Stub
• Spy
• Mock
Friday, June 25, 2010
42. 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());
}
Friday, June 25, 2010
43. DATA PROVIDERS
•1 teste, muitos dados
• Análise completa de diferentes quadros
Friday, June 25, 2010
47. “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
48. 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
49. Especificação Análise Codificação
Manutenção Deploy Testes
CICLO DE DESENVOLVIMENTO
sem TDD
Friday, June 25, 2010
58. Especificação Análise Codificação
Manutenção Deploy Testes
CICLO DE DESENVOLVIMENTO
sem TDD
Friday, June 25, 2010
59. Especificação Análise Testes
Manutenção Deploy Codificação
CICLO DE DESENVOLVIMENTO
sem TDD
Friday, June 25, 2010
60. Especificação Análise Testes
Manutenção Deploy Codificação
CICLO DE DESENVOLVIMENTO
sem TDD
Friday, June 25, 2010
61. Testes
O que desejamos que <método> faça?
Massa de dados para Teste
Codificação
Como <método> fará o que precisa?
Sem formulários, teste direto o backend com os dados
Friday, June 25, 2010
62. Especificação Análise Testes
Manutenção Deploy Codificação
CICLO DE DESENVOLVIMENTO
sem com TDD
Friday, June 25, 2010
63. 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
64. RINSE AND REPEAT
Automatize seus testes e garanta qualidade da equipe
Friday, June 25, 2010
65. CONTINUOS INTEGRATION
• “Integração contínua”
• Processo automatizado
• Executado após cada commit
• Identifica falhas
• Identifica culpados
• Controla qualidade
Friday, June 25, 2010