Por mais que você tente programar da melhor maneira possível, com certeza irá cometer erros. E não é isso que definirá se você é um mau ou bom programador.
O que realmente irá diferenciá-lo dos demais, é de que forma você usa testes para detectar seus erros. E é disso que vamos falar hoje: sobre automatização de testes com o PHPUnit.
PHPUnit: o que é e como usá-lo
Se você nunca trabalhou com testes automatizados, aqui está sua oportunidade.
Não é uma tarefa fácil, mas não se preocupe, não é um bicho de sete cabeças. No início tomará tempo. Em média você levará um dia para implementar os testes necessários, para cada dia de desenvolvimento propriamente dito.
Esse tempo “perdido” no início, será compensado muitas vezes no final do projeto.
Uma ferramenta muito interessante e fácil de usar (possui documentação em português) para a linguagem PHP, é o PHPUnit. O PHPUnit é um framework de testes que pertence à família xUnit de frameworks de teste. É utilizado para escrever e rodar testes automatizados.
Com ele, você poderá fazer testes unitários, ou seja, verificar se seu programa se comporta como o esperado. E fazer uma bateria de testes, fragmentos de código executável que automaticamente testam se as partes (unidades) do programa estão corretas.
Por quê testar o PHPUnit
Para que sua rotina de testes automatizados seja eficiente, é necessário implementá-lo desde o início, do desenvolvimento e da aplicação. Somente assim seus testes serão confiáveis e funcionarão da forma que deseja.
Quando deixamos para testar o software somente depois de lançado, a maioria dos erros nem sequer chegam a ser encontrados. E o custo de consertar a minoria que você encontrará, é tão alto, que terá que escolher qual dos erros são mais relevantes e causarão mais problemas, para assim, poder consertá-los.
Leia também: Node.js é com a ServerDo.in
Quais as vantagens
- Os testes são automatizados, ou seja, não precisam de intervenção manual durante sua execução;
- São executados continuamente durante o ciclo de desenvolvimento;
- Detectam falhas tanto de digitação e lógica, como também, comportamentos inesperados.
Como realizar o PHPUnit?
Vamos à parte que interessa: como realizar esses tais testes automatizados? Abaixo você pode conferir um exemplo simples dessa aplicação.
class Calculadora{
public function somar($a, $b){
return $a+$b;
}
public function subtrair($a, $b){
return $a-$b;
}
}
// Teste da classe
$calc = new Calculadora();
$soma = $calc->somar(2, 2);
$subracao = $calc->subtrair(2, 2);
echo ‘2 + 2 = ‘ . $soma;
echo ‘2 – 2 = ‘ . $subtracao;
// Beleza, a classe funciona conforme esperávamos!
O exemplo acima ilustra uma prática bem comum no dia-a-dia dos programadores: Inserir vários echo() e print() para testar o funcionamento de uma classe/função.
O PHPUnit é uma framework que tem como objetivo automatizar e padronizar a forma como o código é testado. Sendo assim, toda vez que sentir vontade de escrever um echo() ou algo parecido, crie um teste da seguinte forma:
// Especifique o caminho do PHPUnit
require_once ‘/usr/share/php/PHPUnit/Framework.php’;
// Especifique o caminho da classe a ser testada
require_once ‘Classe1.php’;
/* A classe a ser testada se chama “Calculadora”, então a
* classe de teste deverá se chamar “CalculadoraTest” e
* (neste caso) irá herdar de PHPUnit_Framework_TestCase
*/
class CalculadoraTest extends PHPUnit_Framework_TestCase {
// Funções de teste devem ter o prefixo “test”
public function testSoma(){
// A classe a ser testada é instanciada
$calc = new Calculadora();
// Testamos a afirmação que “4” é o resultado de
// passar “2” e “2” (ou seja, 2 + 2 = 4)
$this->assertEquals(‘4’, $calc->somar(2, 2));
}
public function testSubtracao(){
// idem (veja função acima)
$calc = new Calculadora();
$this->assertEquals(‘0’, $calc->subtrair(2, 2));
}
}
Segue resultado da execução dessa rotina de testes:
PHPUnit 3.3.16 by Sebastian Bergmann.
Time: 0 seconds
OK (2 tests, 2 assertions)
// Beleza, a classe funciona conforme esperávamos!
Criamos uma classe (CalculadoraTest) de teste para testar a nossa classe (Calculadora) e usamos o PHPUnit para testar o funcionamento esperado.
Inicialmente pode parecer bem mais simples inserir um echo() e verificar manualmente, mas ao longo prazo, usar o PHPUnit trará diversas vantagens, como:
- Os testes ficam separados do código-fonte da aplicação. Desta forma não corremos o risco de esquecer testes no meio do código. Devido à separação, também não é necessário comentar e descomentar inúmeras vezes as linhas de teste inseridas manualmente;
- Para aplicações um pouco mais complexas (com várias classes interagindo juntas) às vezes não é possível colocar echo() ou print() em qualquer lugar.
- Usando o PHPUnit criamos vários testes e sempre que desejarmos, podemos rodá-los novamente para testar modificações.
- Não precisamos fazer nada na hora de colocar a aplicação no ar. Simplesmente não fazemos o upload da pasta de testes! O código-fonte original segue intacto.
Leia também: Qual servidor meu site ou sistema precisa?
Como funciona? É simples!
- Crie uma classe de teste para testar uma classe já existente;
- Execute os testes no terminal (ou prompt de comando) e veja os resultados;
Premissas para criar os testes:
- Os testes para a classe “Calculadora” (Calculadora.php) deverão ser localizados dentro da classe “CalculadoraTest” (CalculadoraTest.php). Sempre use o sufixo “Test”, da seguinte forma: (NomeDaClasseTest);
- Na maioria dos casos, a classe de teste irá herdar (extends) os métodos da classe PHPUnit_Framework_TestCase;
- Os testes deverão ser funções públicas com o prefixo “test” (testSomar, testSubtrair, etc);
- Os testes são baseados em afirmações, ou seja: afirmamos que o resultado esperado da função A é igual a B, e testamos a afirmação pra ver se ela procede;
- Usamos funções como assertEquals() para testar afirmações (outros exemplos a seguir).
Algumas afirmações disponíveis (Funções de Teste):
- assertEquals($valor, function()) (afirma que o valor retornado de function() é igual a $valor)
- assertNotEquals($valor, function()) (afirma que o valor retornado da function() não é igual a $valor)
- assertSame($valor, function()) (testa se o objeto retornado é igual a $valor)
- assertTrue(function()) (afirma que o valor retornado é == true)
- assertFalse(function()) (afirma que o valor retornado é == false)
- setExpectedException (avisa sobre uma exceção que deverá ser lançada)
Como rodar os testes
Através do terminal (ou prompt de comando), na pasta do arquivo de teste digite:
phpunit NomeDaClasseTest
# para rodar os testes contidos no arquivo NomeDaClasseTest.php
Como podem perceber, o assunto é bastante extenso e consequentemente impossível de cobrir todas as possibilidades. É possível criar testes para testar se exceções são lançadas conforme esperado, para testar classes de acesso ao banco de dados e muito mais.
O ideal seria implementar isto em uma aplicação que esteja desenvolvendo, ou seja, crie uma pasta para os testes e vá criando testes para as suas classes nela.