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

Preview:

DESCRIPTION

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.

Citation preview

E NO SÉTIMO DIA ELE CRIOU TESTES

TDD e o papel de testes no desenvolvimento de aplicações

Rafael Dohmsrafael@rafaeldohms.com.br

Saturday, July 9, 2011

⚠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

A CRIAÇÃO DO MUNDOdo ponto de vista do desenvolvimento de software

Saturday, July 9, 2011

Saturday, July 9, 2011

Saturday, July 9, 2011

Saturday, July 9, 2011

Saturday, July 9, 2011

Saturday, July 9, 2011

Saturday, July 9, 2011

Saturday, July 9, 2011

Saturday, July 9, 2011

@OCriador

Saturday, July 9, 2011

@OCriador* Adão has joined #earth

* Eva has joined #earthAdão

Eva

Saturday, July 9, 2011

@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

Saturday, July 9, 2011

@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

Saturday, July 9, 2011

@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

Saturday, July 9, 2011

Rafael Dohms

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.

phot

o cr

edit:

Eli W

hite

Saturday, July 9, 2011

TESTESporque você precisa deles, mas ainda não sabe

Sebastian Bergmann

Saturday, July 9, 2011

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 automatizados

Saturday, July 9, 2011

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

Saturday, July 9, 2011

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

Saturday, July 9, 2011

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

Saturday, July 9, 2011

CADA SITUAÇÃO, UMA FERRAMENTA

Frontend Backend PHP

Selenium+

PHPUnit PHPUnit PHPT

Saturday, July 9, 2011

ESCREVENDO TESTESquando você começar, nunca mais vai parar

skoop @flickr

Saturday, July 9, 2011

MANOWARS!

• Sistema de Batalhas

• Garantindo o elemento aleatório

• Ataque: Fixo + Random

• Defesa: Fixo + Random

• Damage: Atk/Def * Random

Saturday, July 9, 2011

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!

Saturday, July 9, 2011

MW_MANOVamos ver de perto o código

Saturday, July 9, 2011

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

Saturday, July 9, 2011

RAIO-X DE UMA SUITE DE TESTES

AllTests

PHPUnit_Framework_TestSuite

Saturday, July 9, 2011

RAIO-X DE UMA SUITE DE TESTES

AllTests

PHPUnit_Framework_TestSuite

ClassXTest

PHPUnit_Framework_TestCase

ClassXTest

PHPUnit_Framework_TestCase

ClassXTest

PHPUnit_Framework_TestCase

Saturday, July 9, 2011

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

...

Saturday, July 9, 2011

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

...

Saturday, July 9, 2011

EXECUÇÃO DA SUITESetUp

TearDown

SetUp

TearDown

SetUp

TearDown

SetUp

TearDown

Para cada teste

Para cada teste

Para cada teste

Saturday, July 9, 2011

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

Saturday, July 9, 2011

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); }

Saturday, July 9, 2011

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); }

Saturday, July 9, 2011

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...

Saturday, July 9, 2011

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

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); }

Interrompe o teste se falhar

Saturday, July 9, 2011

TESTANDO OS BÁSICOS

• Estrutura da Suite

• AllTests.php

• MW_Mano

• Testes do 1 ao 6

Saturday, July 9, 2011

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

Saturday, July 9, 2011

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

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

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

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, Mock

Saturday, July 9, 2011

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

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());}

Saturday, July 9, 2011

DATA PROVIDERS

• Um teste, muitos dados

• Análise completa de diferentes cenários

Saturday, July 9, 2011

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>

Medindo a eficiência de nossos testes

Saturday, July 9, 2011

Saturday, July 9, 2011

TDDNão é sobre testes, é sobre especificações

Test Driven Development

Saturday, July 9, 2011

“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

Saturday, July 9, 2011

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

Saturday, July 9, 2011

CICLO DE DESENVOLVIMENTOsem TDD

Especificação Análise Codificação

TestesDeployManutenção

Saturday, July 9, 2011

Codificação

Saturday, July 9, 2011

Codificação

Saturday, July 9, 2011

Codificação

Saturday, July 9, 2011

Codificação

Saturday, July 9, 2011

Codificação

Saturday, July 9, 2011

Codificação

Saturday, July 9, 2011

Codificação

Saturday, July 9, 2011

Codificação

Saturday, July 9, 2011

CICLO DE DESENVOLVIMENTOsem TDD

Especificação Análise Codificação

TestesDeployManutenção

Saturday, July 9, 2011

CICLO DE DESENVOLVIMENTOsem TDD

Especificação Análise

Codificação

Testes

DeployManutenção

Saturday, July 9, 2011

CICLO DE DESENVOLVIMENTOsem TDD

Especificação Análise

Codificação

Testes

DeployManutenção

Saturday, July 9, 2011

Codificação

Testes

O que desejamos que <método> faça?

Como <método> fará o que precisa?

Quais são os cenários que ele precisa estar preparado para lidar?

Sem formulários, teste direto o backend com os dados

Saturday, July 9, 2011

CICLO DE DESENVOLVIMENTOsem com TDD

Especificação Análise

DeployManutenção Codificação

Testes

Saturday, July 9, 2011

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

Saturday, July 9, 2011

RINSE AND REPEATAutomatize seus testes e garanta qualidade da equipe

Saturday, July 9, 2011

CONTINUOS INTEGRATION

• “Integração contínua”

• Processo automatizado

• Executado após cada commit

• Identifica falhas

• Identifica culpados

• Controla qualidade

Saturday, July 9, 2011

Saturday, July 9, 2011

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

Saturday, July 9, 2011

Saturday, July 9, 2011

Saturday, July 9, 2011

DÚVIDAS?

Saturday, July 9, 2011

Avalie essa palestra: http://joind.in/3571

http://doh.msrafael@doh.ms

Obrigado!

Slides: http://slides.doh.ms

Código: https://github.com/rdohms/ManoWars

Saturday, July 9, 2011