SlideShare uma empresa Scribd logo
Ganhando tempo com Casos de Testes Michael Castillo Granados [email_address] http://dgmike.com.br
Já se sentiu sem saber onde está o erro de sua aplicação? Calma! Isso é mais normal do que parece!
Tenho uma solução para seus problemas! Test-Driven Development
Por que usar? O sistema é percorrido por testes do começo ao fim O código do projeto se torna mais confiável Ganho de tempo nos projetos A equipe pode efetuar testes locais e ao final de um período, executar testes globais verificando se alguém quebrou a programação de outro
O que você precisa? Suite de testes estável: Php_Unit SimpleTest Coragem Bom Senso
Escrevendo os primeiros testes <?php include  ( 'simpletest/autorun.php' ); include  ( 'calculadora.php' ); class  CalculadoraTest  extends  UnitTestCase { function  testSoma() { $ resultado  = soma( 5 ,  6 ); $ this ->assertEqual ($ resultado ,  11 ); } }
Escrevendo os primeiros testes <?php include  ( 'simpletest/autorun.php' ); include  ( 'calculadora.php' ); class CalculadoraTest extends UnitTestCase { function testSoma() { $resultado = soma(5, 6); $this->assertEqual ($resultado, 11); } }
Escrevendo os primeiros testes <?php include ('simpletest/autorun.php'); include ('calculadora.php'); class  CalculadoraTest  extends   UnitTestCase  { function testSoma() { $resultado = soma(5, 6); $this->assertEqual ($resultado, 11); } } O módulo de testes deve extender uma classe especial  da  SimpleTest , neste caso:  UnitTestCase
Escrevendo os primeiros testes <?php include ('simpletest/autorun.php'); include ('calculadora.php'); class CalculadoraTest extends UnitTestCase { function   test Soma() { $resultado = soma(5, 6); $this->assertEqual ($resultado, 11); } } O método deve começar com  test
Escrevendo os primeiros testes <?php include ('simpletest/autorun.php'); include ('calculadora.php'); class CalculadoraTest extends UnitTestCase { function testSoma() { $resultado =  soma (5, 6); $this-> assertEqual  ($resultado, 11); } } assertEqual  verifica se o resultado é igual ao esperado: 11
O primeiro resultado Fatal error:  Call to undefined function  soma() in  calculadora_test.php  on line 6 Isto acontece porque a função  soma  ainda não existe
Resolvendo o problema <?php function  soma ($ a , $ b ) { return  $ a +$ b ; } Uma forma simples de resolver, nada de resolver coisas a mais
Resultado OK Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0
Você ainda pode rodar os testes no seu navegador Falha Sucesso
Vamos complicar um pouco? class  CalculadoraTest  extends   UnitTestCase  { function  testSoma() { $ this ->assertEqual ( soma ( 5 ,  6 ),  11 ); } function  testMultiSoma() { $ this ->assertEqual ( soma ( 5 ,  6 ,  4 ,  6 ,  8 ,  9 ),  38 ); } function  testSomaVazio() { $ this ->assertEqual( soma (),  0 ); } }
E o resultado dos testes muda um pouquinho... calculadora_test.php 1)  Equal expectation fails because [ Integer: 11 ] differs from [ Integer: 38 ] by 27 at [F:wwhpconferencexemplosalculadora_test.php line 11] in  testMultiSoma in CalculadoraTest Exception 1! Unexpected PHP error [ Missing argument 1 for soma() , called in F:wwhpconferencexemplosalculadora_test.php on line 14 and defined] severity [E_WARNING] in [F:wwhpconferencexemplosalculadora.php line 2] in  testSomaVazio in CalculadoraTest Exception 2! Unexpected PHP error [ Missing argument 2 for soma() , called in F:wwhpconferencexemplosalculadora_test.php on line 14 and defined] severity [E_WARNING] in [F:wwhpconferencexemplosalculadora.php line 2] in  testSomaVazio in CalculadoraTest FAILURES!!! Test cases run: 1/1, Passes: 2, Failures: 1, Exceptions: 2
Métodos que podemos verificar assertTrue($x) assertFalse($x) assertNull($x) assertNotNull($x) assertIsA($x, $t) assertNotA($x, $t) assertEqual($x, $y) assertNotEqual($x, $y) assertWithinMargin($x, $y, $m) assertOutsideMargin($x, $y, $m) assertIdentical($x, $y) assertNotIdentical($x, $y) assertReference($x, $y) assertClone($x, $y) assertPattern($p, $x) assertNoPattern($p, $x) expectError($x) assert($e) Ao todo, temos 18 métodos de verificação unitária no SimpleTest
Verificando um erro <?php include_once ('simpletest/autorun.php'); class CometendoErros extends UnitTestCase { function  testEsperandoUmErro() { $this-> expectError ( 'Nao foi possivel somar' ); soma_impossivel (); } } function   soma_impossivel () { trigger_error ( 'Nao foi possivel somar' ); }
Antes e depois de executar testes Métodos especiais  setUp  e  tearDown class  LoggerTest  extends   UnitTestCase  { function  setUp() { @ unlink ( 'registro.log' ); } function  tearDown() { @ unlink ( 'registro.log' ); } function  testLogger() { $ this ->assert False ( file_exists ( 'registro.log' )); logger( 'Mensagem que vai para o log' ); $ this ->assert True ( file_exists ( 'registro.log' )); $this->assert Equal ( file_get_contents ( 'registro.log' ),  “Mensagem que vai para o log.” ); } }
Brincando com o banco de dados <?php class  Db { var   $ con, $ res ; function  __construct () { $ this ->con =  new  PDO( 'mysql:host=localhost;dbname=phpconference' , 'phpconference' ,  'phpconference' ); } function  query ( $ query ) { $ this ->res =  $ this ->con->query( $ query ); } function  total( $ table ) { $ res  =  $ this ->con->query( &quot;SELECT COUNT(*) AS t FROM  $ table &quot; ); return   $ res ->fetchObject()->t; } function  clear ( $ table ) { $ this ->con->query( &quot;DELETE FROM  $ table &quot; ); } } Tomando como base a seguinte classe de manipulação de Banco de dados
E a seguinte tabela do banco Tabela usuario com  primary_key  em  id
Escrevemos o seguinte teste include_once  ( 'simpletest/autorun.php' ); include_once  ( 'db.php' ); include_once  ( 'usuario.php' ); class  UsuarioTest  extends  UnitTestCase { var   $ db ; function  setUp() { $ this ->db = new Db; $ this ->db->clear( 'usuarios' ); } function  testNovoUsuario() { $ usuario = new Usuario(array ( 'nome'   =>  'Michael' , 'idade'  =>  24 , 'sexo'   =>  'masculino' , 'site'   =>  'http://dgmike.com.br' , )); $ this ->assertEqual( $ this ->db->total( 'usuarios' ),  1 ); } }
Escrevemos o seguinte teste include_once  ( 'simpletest/autorun.php' ); include_once  ( 'db.php' ); include_once  ( 'usuario.php' ); class UsuarioTest extends UnitTestCase { var $db; function setUp() { $this->db = new Db; $this->db->clear('usuarios'); } function testNovoUsuario() { $usuario = new Usuario(array ( 'nome'  => 'Michael', 'idade' => 24, 'sexo'  => 'masculino', 'site'  => 'http://dgmike.com.br', )); $this->assertEqual($this->db->total('usuarios'), 1); } } Incluimos os arquivos: - autorun da simpletest - classe de banco de dados - classe Usuário (que iremos testar)
Escrevemos o seguinte teste include_once ('simpletest/autorun.php'); include_once ('db.php'); include_once ('usuario.php'); class UsuarioTest extends UnitTestCase { var $db; function  setUp() { $ this ->db = new Db; $ this ->db->clear( 'usuarios' ); } function testNovoUsuario() { $usuario = new Usuario(array ( 'nome'  => 'Michael', 'idade' => 24, 'sexo'  => 'masculino', 'site'  => 'http://dgmike.com.br', )); $this->assertEqual($this->db->total('usuarios'), 1); } } Ao inicializar, o banco de dados (de testes) é limpo. Podemos inserir também dados de teste caso necessário.
Escrevemos o seguinte teste include_once ('simpletest/autorun.php'); include_once ('db.php'); include_once ('usuario.php'); class UsuarioTest extends UnitTestCase { var $db; function setUp() { $this->db = new Db; $this->db->clear('usuarios'); } function  testNovoUsuario() { $ usuario = new Usuario(array ( 'nome'   =>  'Michael' , 'idade'  =>  24 , 'sexo'   =>  'masculino' , 'site'   =>  'http://dgmike.com.br' , )); $ this ->assertEqual( $ this ->db->total( 'usuarios' ),  1 ); } } Ao usar a classe  Usuario  nosso banco de dados deve adicionar um registro, logo o total de usuários deve ser  1 .
Banco de dados sempre é uma dor de cabeça! Alterar registros, verificar se foram alterados em funções que obviamente adicionam ao banco de dados, reescrever os testes sobre áreas já testadas. Sim, concordo! Trabalhar com banco de dados é uma dor-de-cabeça! Mas nem sempre você precisa se conectar ao banco de dados de verdade
Duck typing: usando mockups Se quacheia como um pato e anda como um pato, então é um pato class  BancoPato { function  query() {} function  numRows() {} } // Gerando o pato Mock :: generate ('BancoPato'); $ banco   = new  MockBancoPato (); // Setando o retorno do método query do meu // objeto de manipulação de banco de dados Pato $ banco ->setReturnValue( 'query' ,  true );
Testes diferentes para retornos diferentes da função  query class  PatoTest  extends  UnitTestCase { function  setUp() { global  $banco, $pato; $banco =  new  MockBancoPato(); $pato =  new  Pato(); } function  testPato() { global  $banco, $pato; $banco->setReturnValue( 'query' ,  true ); $this->assertEqual( 'Voce inseriu um pato com sussesso!' , $pato->insert( array  ( 'Rodrigo' ))); } function  testPatoInvalido() { global  $banco, $pato; $banco->setReturnValue( 'query' ,  false ); $this->assertEqual( 'Ops! Ocorreram falhas ao tentar adicionar um pato' , $pato->insert( array  ( 'Rodrigo' ))); } }
Testando a Web Sim! É possível testar seus formulários. Que tal economizar seus dedos ao preencher aquele formulário enorme? Verificar resultados de busca Verificar se os links o levam para a página correta Verificar se o usuário está logado ou não na conta do sistema
Um exemplo clássico
WebTestCase <?php include_once  ( 'simpletest/web_tester.php' ); class  LoginTest  extends  WebTestCase { function  setUp() { $ db  =  new  Db; $ db ->clear( 'usuarios' ); $ usuario  =  new  Usuario( array  ( 'nome'   =>  'Michael' , 'idade'  => 24, 'sexo'   =>  'masculino' , 'site'   =>  'http://dgmike.com.br' , )); } function  testLoginErrado () { $ this ->get( 'http://localhost/phpconference/exemplos/login.php' ); $ this ->assertTrue($ this ->setField( 'nome' ,  'Augusto' )); $ this ->clickSubmit( 'Login' );  // Clicamos no botão submit $ this ->assertText( 'Login Invalido' );  // Verificamos se o texto existe } }
WebTestCase <?php include_once ('simpletest/web_tester.php'); class LoginTest extends WebTestCase { function setUp() { $db = new Db; $db->clear('usuarios'); $usuario = new Usuario(array ( 'nome'  => 'Michael', 'idade' => 24, 'sexo'  => 'masculino', 'site'  => 'http://dgmike.com.br', )); } function  testLoginErrado () { $ this ->get( 'http://localhost/phpconference/exemplos/login.php' ); $ this ->assertTrue($ this ->setField( 'nome' ,  'Augusto' )); $ this ->clickSubmit( 'Login' );  // Clicamos no botão submit $ this ->assertText( 'Login Invalido' );  // Verificamos se o texto existe } } É aqui que acontece a mágica. Fazemos o script navegar como se fosse o usuário. E nada mais de testar na mão para ver se o formuário está correto.
Tem que rodar os testes separados? <?php require_once ( 'simpletest/autorun.php' ); class  FileTestSuite  extends  TestSuite { function  FileTestSuite() { $this->TestSuite( 'All file tests' ); foreach  ( glob ( '*.test.php' ) as $file) { $this->addTestFile($file); } } }
Mas Mike, não é mais lento escrever tanto teste? NÃO!
Então... onde ganho? Na hora de descobrir onde  aquela função de alteração de última hora afeta seu código A longo prazo são menos falhas a corrigir Tem a certeza que está escrevendo certo Passa a escrever menos  código desnecessário Os testes são automatizados, então não precisam de sua interferência para fazer os testes, mesmo do projeto inteiro
Onde encontrar?

Mais conteúdo relacionado

Mais procurados

Prog web 02-php-primeiros-passos
Prog web 02-php-primeiros-passosProg web 02-php-primeiros-passos
Prog web 02-php-primeiros-passos
Regis Magalhães
 
Php 02 Primeiros Passos
Php 02 Primeiros PassosPhp 02 Primeiros Passos
Php 02 Primeiros Passos
Regis Magalhães
 
PHP Experience 2016 - [Palestra] Keynote: PHP-7
PHP Experience 2016 - [Palestra] Keynote: PHP-7PHP Experience 2016 - [Palestra] Keynote: PHP-7
PHP Experience 2016 - [Palestra] Keynote: PHP-7
iMasters
 
Design patterns
Design patternsDesign patterns
Design patterns
DouglasSoaresAndrSch
 
PHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformancePHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta Performance
Felipe Ribeiro
 
Aula3
Aula3Aula3
Aula3
softeam
 
Hello SAFE World!!!
Hello SAFE World!!!Hello SAFE World!!!
Hello SAFE World!!!
Everaldo Wanderlei Uavniczak
 
Exercicios sequenciais
Exercicios sequenciaisExercicios sequenciais
Exercicios sequenciais
Mirlem Pereira
 
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
Mirlem Pereira
 
Operadores Java
Operadores JavaOperadores Java
Operadores Java
Raphael Marques
 
ReactPHP && programacao assincrona em PHP
ReactPHP && programacao assincrona em PHPReactPHP && programacao assincrona em PHP
ReactPHP && programacao assincrona em PHP
Luis Gustavo Almeida
 
Testes com python: como fazer uma refatoração segura
Testes com python: como fazer uma refatoração seguraTestes com python: como fazer uma refatoração segura
Testes com python: como fazer uma refatoração segura
Valberto Carneiro
 
Curso de Shell Script 10/11
Curso de Shell Script 10/11Curso de Shell Script 10/11
Curso de Shell Script 10/11
Rodrigo Silva
 
Php 07 Cakephp
Php 07 CakephpPhp 07 Cakephp
Php 07 Cakephp
Regis Magalhães
 
Exercícios da Aula de LAB 02
Exercícios da Aula de LAB 02Exercícios da Aula de LAB 02
Exercícios da Aula de LAB 02
thomasdacosta
 
TDD
TDDTDD
BDD com Rails
BDD com RailsBDD com Rails
BDD com Rails
Caue Guerra
 
Proxy, Man-In-The-Middle e testes
Proxy, Man-In-The-Middle e testesProxy, Man-In-The-Middle e testes
Proxy, Man-In-The-Middle e testes
Stanislaw Pusep
 
Desenvolvimento Rápido de Programas Linha de Comando
Desenvolvimento Rápido de Programas Linha de ComandoDesenvolvimento Rápido de Programas Linha de Comando
Desenvolvimento Rápido de Programas Linha de Comando
garux
 
Php 05 Mvc
Php 05 MvcPhp 05 Mvc
Php 05 Mvc
Regis Magalhães
 

Mais procurados (20)

Prog web 02-php-primeiros-passos
Prog web 02-php-primeiros-passosProg web 02-php-primeiros-passos
Prog web 02-php-primeiros-passos
 
Php 02 Primeiros Passos
Php 02 Primeiros PassosPhp 02 Primeiros Passos
Php 02 Primeiros Passos
 
PHP Experience 2016 - [Palestra] Keynote: PHP-7
PHP Experience 2016 - [Palestra] Keynote: PHP-7PHP Experience 2016 - [Palestra] Keynote: PHP-7
PHP Experience 2016 - [Palestra] Keynote: PHP-7
 
Design patterns
Design patternsDesign patterns
Design patterns
 
PHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta PerformancePHP Jedi - Boas Práticas e Alta Performance
PHP Jedi - Boas Práticas e Alta Performance
 
Aula3
Aula3Aula3
Aula3
 
Hello SAFE World!!!
Hello SAFE World!!!Hello SAFE World!!!
Hello SAFE World!!!
 
Exercicios sequenciais
Exercicios sequenciaisExercicios sequenciais
Exercicios sequenciais
 
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
8a. aula -_estrutura_de_controle_de_repeticao_-_while_java
 
Operadores Java
Operadores JavaOperadores Java
Operadores Java
 
ReactPHP && programacao assincrona em PHP
ReactPHP && programacao assincrona em PHPReactPHP && programacao assincrona em PHP
ReactPHP && programacao assincrona em PHP
 
Testes com python: como fazer uma refatoração segura
Testes com python: como fazer uma refatoração seguraTestes com python: como fazer uma refatoração segura
Testes com python: como fazer uma refatoração segura
 
Curso de Shell Script 10/11
Curso de Shell Script 10/11Curso de Shell Script 10/11
Curso de Shell Script 10/11
 
Php 07 Cakephp
Php 07 CakephpPhp 07 Cakephp
Php 07 Cakephp
 
Exercícios da Aula de LAB 02
Exercícios da Aula de LAB 02Exercícios da Aula de LAB 02
Exercícios da Aula de LAB 02
 
TDD
TDDTDD
TDD
 
BDD com Rails
BDD com RailsBDD com Rails
BDD com Rails
 
Proxy, Man-In-The-Middle e testes
Proxy, Man-In-The-Middle e testesProxy, Man-In-The-Middle e testes
Proxy, Man-In-The-Middle e testes
 
Desenvolvimento Rápido de Programas Linha de Comando
Desenvolvimento Rápido de Programas Linha de ComandoDesenvolvimento Rápido de Programas Linha de Comando
Desenvolvimento Rápido de Programas Linha de Comando
 
Php 05 Mvc
Php 05 MvcPhp 05 Mvc
Php 05 Mvc
 

Semelhante a Ganhando tempo com casos de testes

Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnit
Diego Tremper
 
operadores aritméticos, relacionais e lógicos em javascript
operadores aritméticos, relacionais e lógicos em javascriptoperadores aritméticos, relacionais e lógicos em javascript
operadores aritméticos, relacionais e lógicos em javascript
joaoigordk
 
Testes Unitarios Com PostgreSQL
Testes Unitarios Com PostgreSQLTestes Unitarios Com PostgreSQL
Testes Unitarios Com PostgreSQL
Diogo Biazus
 
O que há de novo no PHP 5.3
O que há de novo no PHP 5.3O que há de novo no PHP 5.3
O que há de novo no PHP 5.3
Jose Berardo
 
PHP FrameWARks - FISL
PHP FrameWARks - FISLPHP FrameWARks - FISL
PHP FrameWARks - FISL
Marcio Albuquerque
 
Aula javascript
Aula  javascriptAula  javascript
Aula javascript
Gabriel Moura
 
Programação web ii aulas 06 e 07
Programação web ii   aulas 06 e 07Programação web ii   aulas 06 e 07
Programação web ii aulas 06 e 07
Yuri Bispo
 
JavaScript
JavaScriptJavaScript
PHPUnit e teste de software
PHPUnit e teste de softwarePHPUnit e teste de software
PHPUnit e teste de software
ricardophp
 
Aula5
Aula5Aula5
Aula5
fkimura
 
Conteúdo teórico sobre funções e cookies
Conteúdo teórico sobre funções e cookiesConteúdo teórico sobre funções e cookies
Conteúdo teórico sobre funções e cookies
suellencarolinerosa
 
Php 08 Oo
Php 08 OoPhp 08 Oo
Php 08 Oo
Regis Magalhães
 
Otimização e Escalabilidade
Otimização e EscalabilidadeOtimização e Escalabilidade
Otimização e Escalabilidade
metzen
 
Minicurso php
Minicurso phpMinicurso php
Minicurso php
Danilo Costa
 
Groovy para javeiros - Migração Painless
Groovy para javeiros - Migração PainlessGroovy para javeiros - Migração Painless
Groovy para javeiros - Migração Painless
Rafael Farias Silva
 
Tema 2 | Linguagem PHP Básico (I)
Tema 2 | Linguagem PHP Básico (I)Tema 2 | Linguagem PHP Básico (I)
Tema 2 | Linguagem PHP Básico (I)
Henry Raúl González Brito
 
Javascript
JavascriptJavascript
Javascript
Fernando Simeone
 
Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Removendo o cheiro ruim do seu código - PHPSC Conf 2011Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Luís Cobucci
 
Html5 storage api
Html5 storage apiHtml5 storage api
Html5 storage api
Suissa
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao java
Armando Daniel
 

Semelhante a Ganhando tempo com casos de testes (20)

Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnit
 
operadores aritméticos, relacionais e lógicos em javascript
operadores aritméticos, relacionais e lógicos em javascriptoperadores aritméticos, relacionais e lógicos em javascript
operadores aritméticos, relacionais e lógicos em javascript
 
Testes Unitarios Com PostgreSQL
Testes Unitarios Com PostgreSQLTestes Unitarios Com PostgreSQL
Testes Unitarios Com PostgreSQL
 
O que há de novo no PHP 5.3
O que há de novo no PHP 5.3O que há de novo no PHP 5.3
O que há de novo no PHP 5.3
 
PHP FrameWARks - FISL
PHP FrameWARks - FISLPHP FrameWARks - FISL
PHP FrameWARks - FISL
 
Aula javascript
Aula  javascriptAula  javascript
Aula javascript
 
Programação web ii aulas 06 e 07
Programação web ii   aulas 06 e 07Programação web ii   aulas 06 e 07
Programação web ii aulas 06 e 07
 
JavaScript
JavaScriptJavaScript
JavaScript
 
PHPUnit e teste de software
PHPUnit e teste de softwarePHPUnit e teste de software
PHPUnit e teste de software
 
Aula5
Aula5Aula5
Aula5
 
Conteúdo teórico sobre funções e cookies
Conteúdo teórico sobre funções e cookiesConteúdo teórico sobre funções e cookies
Conteúdo teórico sobre funções e cookies
 
Php 08 Oo
Php 08 OoPhp 08 Oo
Php 08 Oo
 
Otimização e Escalabilidade
Otimização e EscalabilidadeOtimização e Escalabilidade
Otimização e Escalabilidade
 
Minicurso php
Minicurso phpMinicurso php
Minicurso php
 
Groovy para javeiros - Migração Painless
Groovy para javeiros - Migração PainlessGroovy para javeiros - Migração Painless
Groovy para javeiros - Migração Painless
 
Tema 2 | Linguagem PHP Básico (I)
Tema 2 | Linguagem PHP Básico (I)Tema 2 | Linguagem PHP Básico (I)
Tema 2 | Linguagem PHP Básico (I)
 
Javascript
JavascriptJavascript
Javascript
 
Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Removendo o cheiro ruim do seu código - PHPSC Conf 2011Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Removendo o cheiro ruim do seu código - PHPSC Conf 2011
 
Html5 storage api
Html5 storage apiHtml5 storage api
Html5 storage api
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao java
 

Mais de Michael Castillo Granados

Docker: uma visão geral
Docker: uma visão geralDocker: uma visão geral
Docker: uma visão geral
Michael Castillo Granados
 
Docker compose
Docker composeDocker compose
Design patterns de uma vez por todas
Design patterns de uma vez por todasDesign patterns de uma vez por todas
Design patterns de uma vez por todas
Michael Castillo Granados
 
Design patterns: resolvendo problemas comuns (ruby)
Design patterns: resolvendo problemas comuns (ruby)Design patterns: resolvendo problemas comuns (ruby)
Design patterns: resolvendo problemas comuns (ruby)
Michael Castillo Granados
 
Transformando o wp em uma loja virtual
Transformando o wp em uma loja virtualTransformando o wp em uma loja virtual
Transformando o wp em uma loja virtual
Michael Castillo Granados
 
Ecommerce, mais simples do que parece
Ecommerce, mais simples do que pareceEcommerce, mais simples do que parece
Ecommerce, mais simples do que parece
Michael Castillo Granados
 
Da argila ao forte: como desenvolver uma loja com PagSeguro
Da argila ao forte: como desenvolver uma loja com PagSeguroDa argila ao forte: como desenvolver uma loja com PagSeguro
Da argila ao forte: como desenvolver uma loja com PagSeguro
Michael Castillo Granados
 
Da Argila Ao Forte - Como desenvolver uma loja virtual
Da Argila Ao Forte - Como desenvolver uma loja virtualDa Argila Ao Forte - Como desenvolver uma loja virtual
Da Argila Ao Forte - Como desenvolver uma loja virtual
Michael Castillo Granados
 

Mais de Michael Castillo Granados (8)

Docker: uma visão geral
Docker: uma visão geralDocker: uma visão geral
Docker: uma visão geral
 
Docker compose
Docker composeDocker compose
Docker compose
 
Design patterns de uma vez por todas
Design patterns de uma vez por todasDesign patterns de uma vez por todas
Design patterns de uma vez por todas
 
Design patterns: resolvendo problemas comuns (ruby)
Design patterns: resolvendo problemas comuns (ruby)Design patterns: resolvendo problemas comuns (ruby)
Design patterns: resolvendo problemas comuns (ruby)
 
Transformando o wp em uma loja virtual
Transformando o wp em uma loja virtualTransformando o wp em uma loja virtual
Transformando o wp em uma loja virtual
 
Ecommerce, mais simples do que parece
Ecommerce, mais simples do que pareceEcommerce, mais simples do que parece
Ecommerce, mais simples do que parece
 
Da argila ao forte: como desenvolver uma loja com PagSeguro
Da argila ao forte: como desenvolver uma loja com PagSeguroDa argila ao forte: como desenvolver uma loja com PagSeguro
Da argila ao forte: como desenvolver uma loja com PagSeguro
 
Da Argila Ao Forte - Como desenvolver uma loja virtual
Da Argila Ao Forte - Como desenvolver uma loja virtualDa Argila Ao Forte - Como desenvolver uma loja virtual
Da Argila Ao Forte - Como desenvolver uma loja virtual
 

Último

ExpoGestão 2024 - Inteligência Artificial – A revolução no mundo dos negócios
ExpoGestão 2024 - Inteligência Artificial – A revolução no mundo dos negóciosExpoGestão 2024 - Inteligência Artificial – A revolução no mundo dos negócios
ExpoGestão 2024 - Inteligência Artificial – A revolução no mundo dos negócios
ExpoGestão
 
INTELIGÊNCIA ARTIFICIAL + COMPUTAÇÃO QUÂNTICA = MAIOR REVOLUÇÃO TECNOLÓGICA D...
INTELIGÊNCIA ARTIFICIAL + COMPUTAÇÃO QUÂNTICA = MAIOR REVOLUÇÃO TECNOLÓGICA D...INTELIGÊNCIA ARTIFICIAL + COMPUTAÇÃO QUÂNTICA = MAIOR REVOLUÇÃO TECNOLÓGICA D...
INTELIGÊNCIA ARTIFICIAL + COMPUTAÇÃO QUÂNTICA = MAIOR REVOLUÇÃO TECNOLÓGICA D...
Faga1939
 
Subindo uma aplicação WordPress em docker na AWS
Subindo uma aplicação WordPress em docker na AWSSubindo uma aplicação WordPress em docker na AWS
Subindo uma aplicação WordPress em docker na AWS
Ismael Ash
 
se38_layout_erro_xxxxxxxxxxxxxxxxxx.docx
se38_layout_erro_xxxxxxxxxxxxxxxxxx.docxse38_layout_erro_xxxxxxxxxxxxxxxxxx.docx
se38_layout_erro_xxxxxxxxxxxxxxxxxx.docx
ronaldos10
 
ExpoGestão 2024 - Desvendando um mundo em ebulição
ExpoGestão 2024 - Desvendando um mundo em ebuliçãoExpoGestão 2024 - Desvendando um mundo em ebulição
ExpoGestão 2024 - Desvendando um mundo em ebulição
ExpoGestão
 
Ferramentas que irão te ajudar a entrar no mundo de DevOps/CLoud
Ferramentas que irão te ajudar a entrar no mundo de   DevOps/CLoudFerramentas que irão te ajudar a entrar no mundo de   DevOps/CLoud
Ferramentas que irão te ajudar a entrar no mundo de DevOps/CLoud
Ismael Ash
 

Último (6)

ExpoGestão 2024 - Inteligência Artificial – A revolução no mundo dos negócios
ExpoGestão 2024 - Inteligência Artificial – A revolução no mundo dos negóciosExpoGestão 2024 - Inteligência Artificial – A revolução no mundo dos negócios
ExpoGestão 2024 - Inteligência Artificial – A revolução no mundo dos negócios
 
INTELIGÊNCIA ARTIFICIAL + COMPUTAÇÃO QUÂNTICA = MAIOR REVOLUÇÃO TECNOLÓGICA D...
INTELIGÊNCIA ARTIFICIAL + COMPUTAÇÃO QUÂNTICA = MAIOR REVOLUÇÃO TECNOLÓGICA D...INTELIGÊNCIA ARTIFICIAL + COMPUTAÇÃO QUÂNTICA = MAIOR REVOLUÇÃO TECNOLÓGICA D...
INTELIGÊNCIA ARTIFICIAL + COMPUTAÇÃO QUÂNTICA = MAIOR REVOLUÇÃO TECNOLÓGICA D...
 
Subindo uma aplicação WordPress em docker na AWS
Subindo uma aplicação WordPress em docker na AWSSubindo uma aplicação WordPress em docker na AWS
Subindo uma aplicação WordPress em docker na AWS
 
se38_layout_erro_xxxxxxxxxxxxxxxxxx.docx
se38_layout_erro_xxxxxxxxxxxxxxxxxx.docxse38_layout_erro_xxxxxxxxxxxxxxxxxx.docx
se38_layout_erro_xxxxxxxxxxxxxxxxxx.docx
 
ExpoGestão 2024 - Desvendando um mundo em ebulição
ExpoGestão 2024 - Desvendando um mundo em ebuliçãoExpoGestão 2024 - Desvendando um mundo em ebulição
ExpoGestão 2024 - Desvendando um mundo em ebulição
 
Ferramentas que irão te ajudar a entrar no mundo de DevOps/CLoud
Ferramentas que irão te ajudar a entrar no mundo de   DevOps/CLoudFerramentas que irão te ajudar a entrar no mundo de   DevOps/CLoud
Ferramentas que irão te ajudar a entrar no mundo de DevOps/CLoud
 

Ganhando tempo com casos de testes

  • 1. Ganhando tempo com Casos de Testes Michael Castillo Granados [email_address] http://dgmike.com.br
  • 2. Já se sentiu sem saber onde está o erro de sua aplicação? Calma! Isso é mais normal do que parece!
  • 3. Tenho uma solução para seus problemas! Test-Driven Development
  • 4. Por que usar? O sistema é percorrido por testes do começo ao fim O código do projeto se torna mais confiável Ganho de tempo nos projetos A equipe pode efetuar testes locais e ao final de um período, executar testes globais verificando se alguém quebrou a programação de outro
  • 5. O que você precisa? Suite de testes estável: Php_Unit SimpleTest Coragem Bom Senso
  • 6. Escrevendo os primeiros testes <?php include ( 'simpletest/autorun.php' ); include ( 'calculadora.php' ); class CalculadoraTest extends UnitTestCase { function testSoma() { $ resultado = soma( 5 , 6 ); $ this ->assertEqual ($ resultado , 11 ); } }
  • 7. Escrevendo os primeiros testes <?php include ( 'simpletest/autorun.php' ); include ( 'calculadora.php' ); class CalculadoraTest extends UnitTestCase { function testSoma() { $resultado = soma(5, 6); $this->assertEqual ($resultado, 11); } }
  • 8. Escrevendo os primeiros testes <?php include ('simpletest/autorun.php'); include ('calculadora.php'); class CalculadoraTest extends UnitTestCase { function testSoma() { $resultado = soma(5, 6); $this->assertEqual ($resultado, 11); } } O módulo de testes deve extender uma classe especial da SimpleTest , neste caso: UnitTestCase
  • 9. Escrevendo os primeiros testes <?php include ('simpletest/autorun.php'); include ('calculadora.php'); class CalculadoraTest extends UnitTestCase { function test Soma() { $resultado = soma(5, 6); $this->assertEqual ($resultado, 11); } } O método deve começar com test
  • 10. Escrevendo os primeiros testes <?php include ('simpletest/autorun.php'); include ('calculadora.php'); class CalculadoraTest extends UnitTestCase { function testSoma() { $resultado = soma (5, 6); $this-> assertEqual ($resultado, 11); } } assertEqual verifica se o resultado é igual ao esperado: 11
  • 11. O primeiro resultado Fatal error: Call to undefined function soma() in calculadora_test.php on line 6 Isto acontece porque a função soma ainda não existe
  • 12. Resolvendo o problema <?php function soma ($ a , $ b ) { return $ a +$ b ; } Uma forma simples de resolver, nada de resolver coisas a mais
  • 13. Resultado OK Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0
  • 14. Você ainda pode rodar os testes no seu navegador Falha Sucesso
  • 15. Vamos complicar um pouco? class CalculadoraTest extends UnitTestCase { function testSoma() { $ this ->assertEqual ( soma ( 5 , 6 ), 11 ); } function testMultiSoma() { $ this ->assertEqual ( soma ( 5 , 6 , 4 , 6 , 8 , 9 ), 38 ); } function testSomaVazio() { $ this ->assertEqual( soma (), 0 ); } }
  • 16. E o resultado dos testes muda um pouquinho... calculadora_test.php 1) Equal expectation fails because [ Integer: 11 ] differs from [ Integer: 38 ] by 27 at [F:wwhpconferencexemplosalculadora_test.php line 11] in testMultiSoma in CalculadoraTest Exception 1! Unexpected PHP error [ Missing argument 1 for soma() , called in F:wwhpconferencexemplosalculadora_test.php on line 14 and defined] severity [E_WARNING] in [F:wwhpconferencexemplosalculadora.php line 2] in testSomaVazio in CalculadoraTest Exception 2! Unexpected PHP error [ Missing argument 2 for soma() , called in F:wwhpconferencexemplosalculadora_test.php on line 14 and defined] severity [E_WARNING] in [F:wwhpconferencexemplosalculadora.php line 2] in testSomaVazio in CalculadoraTest FAILURES!!! Test cases run: 1/1, Passes: 2, Failures: 1, Exceptions: 2
  • 17. Métodos que podemos verificar assertTrue($x) assertFalse($x) assertNull($x) assertNotNull($x) assertIsA($x, $t) assertNotA($x, $t) assertEqual($x, $y) assertNotEqual($x, $y) assertWithinMargin($x, $y, $m) assertOutsideMargin($x, $y, $m) assertIdentical($x, $y) assertNotIdentical($x, $y) assertReference($x, $y) assertClone($x, $y) assertPattern($p, $x) assertNoPattern($p, $x) expectError($x) assert($e) Ao todo, temos 18 métodos de verificação unitária no SimpleTest
  • 18. Verificando um erro <?php include_once ('simpletest/autorun.php'); class CometendoErros extends UnitTestCase { function testEsperandoUmErro() { $this-> expectError ( 'Nao foi possivel somar' ); soma_impossivel (); } } function soma_impossivel () { trigger_error ( 'Nao foi possivel somar' ); }
  • 19. Antes e depois de executar testes Métodos especiais setUp e tearDown class LoggerTest extends UnitTestCase { function setUp() { @ unlink ( 'registro.log' ); } function tearDown() { @ unlink ( 'registro.log' ); } function testLogger() { $ this ->assert False ( file_exists ( 'registro.log' )); logger( 'Mensagem que vai para o log' ); $ this ->assert True ( file_exists ( 'registro.log' )); $this->assert Equal ( file_get_contents ( 'registro.log' ), “Mensagem que vai para o log.” ); } }
  • 20. Brincando com o banco de dados <?php class Db { var $ con, $ res ; function __construct () { $ this ->con = new PDO( 'mysql:host=localhost;dbname=phpconference' , 'phpconference' , 'phpconference' ); } function query ( $ query ) { $ this ->res = $ this ->con->query( $ query ); } function total( $ table ) { $ res = $ this ->con->query( &quot;SELECT COUNT(*) AS t FROM $ table &quot; ); return $ res ->fetchObject()->t; } function clear ( $ table ) { $ this ->con->query( &quot;DELETE FROM $ table &quot; ); } } Tomando como base a seguinte classe de manipulação de Banco de dados
  • 21. E a seguinte tabela do banco Tabela usuario com primary_key em id
  • 22. Escrevemos o seguinte teste include_once ( 'simpletest/autorun.php' ); include_once ( 'db.php' ); include_once ( 'usuario.php' ); class UsuarioTest extends UnitTestCase { var $ db ; function setUp() { $ this ->db = new Db; $ this ->db->clear( 'usuarios' ); } function testNovoUsuario() { $ usuario = new Usuario(array ( 'nome' => 'Michael' , 'idade' => 24 , 'sexo' => 'masculino' , 'site' => 'http://dgmike.com.br' , )); $ this ->assertEqual( $ this ->db->total( 'usuarios' ), 1 ); } }
  • 23. Escrevemos o seguinte teste include_once ( 'simpletest/autorun.php' ); include_once ( 'db.php' ); include_once ( 'usuario.php' ); class UsuarioTest extends UnitTestCase { var $db; function setUp() { $this->db = new Db; $this->db->clear('usuarios'); } function testNovoUsuario() { $usuario = new Usuario(array ( 'nome' => 'Michael', 'idade' => 24, 'sexo' => 'masculino', 'site' => 'http://dgmike.com.br', )); $this->assertEqual($this->db->total('usuarios'), 1); } } Incluimos os arquivos: - autorun da simpletest - classe de banco de dados - classe Usuário (que iremos testar)
  • 24. Escrevemos o seguinte teste include_once ('simpletest/autorun.php'); include_once ('db.php'); include_once ('usuario.php'); class UsuarioTest extends UnitTestCase { var $db; function setUp() { $ this ->db = new Db; $ this ->db->clear( 'usuarios' ); } function testNovoUsuario() { $usuario = new Usuario(array ( 'nome' => 'Michael', 'idade' => 24, 'sexo' => 'masculino', 'site' => 'http://dgmike.com.br', )); $this->assertEqual($this->db->total('usuarios'), 1); } } Ao inicializar, o banco de dados (de testes) é limpo. Podemos inserir também dados de teste caso necessário.
  • 25. Escrevemos o seguinte teste include_once ('simpletest/autorun.php'); include_once ('db.php'); include_once ('usuario.php'); class UsuarioTest extends UnitTestCase { var $db; function setUp() { $this->db = new Db; $this->db->clear('usuarios'); } function testNovoUsuario() { $ usuario = new Usuario(array ( 'nome' => 'Michael' , 'idade' => 24 , 'sexo' => 'masculino' , 'site' => 'http://dgmike.com.br' , )); $ this ->assertEqual( $ this ->db->total( 'usuarios' ), 1 ); } } Ao usar a classe Usuario nosso banco de dados deve adicionar um registro, logo o total de usuários deve ser 1 .
  • 26. Banco de dados sempre é uma dor de cabeça! Alterar registros, verificar se foram alterados em funções que obviamente adicionam ao banco de dados, reescrever os testes sobre áreas já testadas. Sim, concordo! Trabalhar com banco de dados é uma dor-de-cabeça! Mas nem sempre você precisa se conectar ao banco de dados de verdade
  • 27. Duck typing: usando mockups Se quacheia como um pato e anda como um pato, então é um pato class BancoPato { function query() {} function numRows() {} } // Gerando o pato Mock :: generate ('BancoPato'); $ banco = new MockBancoPato (); // Setando o retorno do método query do meu // objeto de manipulação de banco de dados Pato $ banco ->setReturnValue( 'query' , true );
  • 28. Testes diferentes para retornos diferentes da função query class PatoTest extends UnitTestCase { function setUp() { global $banco, $pato; $banco = new MockBancoPato(); $pato = new Pato(); } function testPato() { global $banco, $pato; $banco->setReturnValue( 'query' , true ); $this->assertEqual( 'Voce inseriu um pato com sussesso!' , $pato->insert( array ( 'Rodrigo' ))); } function testPatoInvalido() { global $banco, $pato; $banco->setReturnValue( 'query' , false ); $this->assertEqual( 'Ops! Ocorreram falhas ao tentar adicionar um pato' , $pato->insert( array ( 'Rodrigo' ))); } }
  • 29. Testando a Web Sim! É possível testar seus formulários. Que tal economizar seus dedos ao preencher aquele formulário enorme? Verificar resultados de busca Verificar se os links o levam para a página correta Verificar se o usuário está logado ou não na conta do sistema
  • 31. WebTestCase <?php include_once ( 'simpletest/web_tester.php' ); class LoginTest extends WebTestCase { function setUp() { $ db = new Db; $ db ->clear( 'usuarios' ); $ usuario = new Usuario( array ( 'nome' => 'Michael' , 'idade' => 24, 'sexo' => 'masculino' , 'site' => 'http://dgmike.com.br' , )); } function testLoginErrado () { $ this ->get( 'http://localhost/phpconference/exemplos/login.php' ); $ this ->assertTrue($ this ->setField( 'nome' , 'Augusto' )); $ this ->clickSubmit( 'Login' ); // Clicamos no botão submit $ this ->assertText( 'Login Invalido' ); // Verificamos se o texto existe } }
  • 32. WebTestCase <?php include_once ('simpletest/web_tester.php'); class LoginTest extends WebTestCase { function setUp() { $db = new Db; $db->clear('usuarios'); $usuario = new Usuario(array ( 'nome' => 'Michael', 'idade' => 24, 'sexo' => 'masculino', 'site' => 'http://dgmike.com.br', )); } function testLoginErrado () { $ this ->get( 'http://localhost/phpconference/exemplos/login.php' ); $ this ->assertTrue($ this ->setField( 'nome' , 'Augusto' )); $ this ->clickSubmit( 'Login' ); // Clicamos no botão submit $ this ->assertText( 'Login Invalido' ); // Verificamos se o texto existe } } É aqui que acontece a mágica. Fazemos o script navegar como se fosse o usuário. E nada mais de testar na mão para ver se o formuário está correto.
  • 33. Tem que rodar os testes separados? <?php require_once ( 'simpletest/autorun.php' ); class FileTestSuite extends TestSuite { function FileTestSuite() { $this->TestSuite( 'All file tests' ); foreach ( glob ( '*.test.php' ) as $file) { $this->addTestFile($file); } } }
  • 34. Mas Mike, não é mais lento escrever tanto teste? NÃO!
  • 35. Então... onde ganho? Na hora de descobrir onde aquela função de alteração de última hora afeta seu código A longo prazo são menos falhas a corrigir Tem a certeza que está escrevendo certo Passa a escrever menos código desnecessário Os testes são automatizados, então não precisam de sua interferência para fazer os testes, mesmo do projeto inteiro