[vc_row][vc_column][vc_column_text]Atenção! Este post é de Junho de 2013, muitas coisas evoluíram desde então, procure aqui no blog mesmo por conteúdos mais atualizados.

A um bom tempo que venho bolando praticar TDD fora do framework que utilizo, o CakePHP. Dias atrás “brinquei” um pouquinho e percebi que realizar testes fora do ambiente do framework é mais simples do que eu imaginava, aqui vai um pequeno exemplo de como você também pode fazer para iniciar desenvolver com orienteação a testes.

Do que precisamos?

  • PHP >= 5.3.*
  • PHPUnit
  • Xdebug

Os exemplos foram todos codados em ambiente Linux  (Debian 7) utilizando a IDE Netbeans.

Primeiramente você deve instalar o PHP, espero que pelo menos isso você já tenha em sua máquina, não me envergonhe… Em seguida o PHPUnit que não vou fornecer o procedimento de instalação por ser muito simples e está muito bem documentado em português inclusive no site oficial www.phpunit.de e por último o xdebug pra gente gerar o coverage de nossos testes. O coverage é opcional mas é uma ferramenta excelente para que você possa analisar qual o percentual de seu código está coberto por testes além de um ótimo debugger para o PHP. Para instalar o xdebug no Linux Debian-like basta um comando #apt-get install php5-xdebug, já para Windows siga os passos descritos na página oficial www.xdebug.org.

 

 Iniciando

Primeiramente crie um arquivo em PHP, sugiro por meios didáticos que o nome seja UserTest.php. Nele, logo no início informamos que precisamos do PHPUnit, com isso basta dar um require em PHPUnit/Autoload.php.

Após isto crie uma classe chamada User, apenas a crie e deixe-a vazia. Feito isto é hora de criar a classe de testes, nomeie-a como UserTest e extenda-a da classe PHPUnit_Framework_TestCase conforme a imagem abaixo.

1-classes

 

Agora vamos instanciar a classe User em nossa classe de teste a partir do método setUp que é executado automaticamente quando executado o PHPUnit.

2-setUp

 

Aí já temos um começo… faltam alguns passos, mas são muito simples, fica calmo.

Abra o terminal do seu Sistema Operacional, no meu caso Konsole por utilizar Debian com KDE, entre na pasta onde encontra-se seu projeto de teste e, com o PHPUnit instalado corretamente você pode o executar simplesmente digitando $phpunit NomeDaClasseDeTestes isto fará todos os testes existentes nela seja executados. Em nosso caso ainda não existem testes o que nos retornará uma falha indicando da falta de testes na classe.

Dica: para que a visualização dos resultados dos testes se torne mais intuitiva podemos habilitar cores adicionado o parâmetro –colors antes do nome da classe de teste. Em nosso caso a execução correta do teste seria $ phpunit –colors UserTest

 

3-rodando-phpUnit

 

Agora que já sabemos que teremos de criar um teste ao menos, vamos o fazer. Não sei se é algo realmente necessário mas eu sempre gosto de testar se a classe instanciada é a esperada, com isso crio um método nomeando-o como testInstanceOf, isto é, sempre que se tratar de um teste o nome do método deve iniciar com a palavra test em minúsculo seguido da descrição desejada em camelCased. Agora ao digitar no terminal $ phpunit –colors UserTest haverá um teste que passará, olha só…

4-instanceOf

 

Note que acima foi apenas um simples teste e este normalmente passará, a não ser que você faça-o quebrar propositalmente. Então para de fato levarmos o TDD em sua correta implementação (vermelho, verde, refatora) devemos criar um teste que quebre, faremos o mesmo abaixo .

5-firstTest-1

Perceba que setamos um nome e depois demos um assertEquals do nome esperado (à esquerda) com o nome retornado (à direita).

Dica: Leia os assertions do PHPUnit para conhecer as possibilidades, visto que não é o intuito deste post abranger nada além da asserção de equivalência. https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.assertions.

Agora lembre-se de que chamamos o método setName e em seguida o getName, porém ambos não existem ainda. Isto fará o teste quebrar, mas esta não é a única forma de quebra de teste, outra forma é, o método existindo porém não comportando-se conforme o esperado. Ao executar $ phpunit –colors UserTest há inúmeras linhas de erro, erros estes que corrigiremos a seguir.

5-firstTest-2

 

Na classe User (não na UserTest) criaremos uma variável privada $name e seu getter e setter. Agora ao executarmos $ phpunit –colors UserTest o teste simplesmete ficará verde, olha só que legal!!!

5-firstTest-3

Isto porque tanto o método setName quanto o getName da classe testada comportaram-se conforme o esperado.

 

Vamos fazer mais um teste quebrar? Que tal gerar uma senha aleatória para o usuário, seguindo um exemplo de um formulário de recuperação de senha onde uma senha provisória é enviada ao email do solicitante.

Criamos o teste primeiro (conforme as boas práticas do TDD sugerem: primeiro o teste e em seguida o código “definitivo”). Desta vez assertaremos a NÃO equivalênia, ou seja, testaremos se a senha retornada não é nula. Neste exemplo utilizaremos um recurso bastante útil do PHPUnit que é uma mensagem de informação a respeito do erro, definimos como “Empty Password” com isso ao teste quebrar a gente poderá ver além de qual teste é, uma mensagem mais amigável a respeito do erro. Execute o comando $ phpunit –colors UserTest e veja mais um teste quebrar.

7-secondTest-Password-1

 

Agora vamos à programação que não só fará o teste passar mas sim como sua aplicação se comportará. Desta vez o teste passa e você tem a certeza de que qualquer alteração futura no método newPassword da classe User ao alterar sua lógica será rapidamente visualizado se houveram erros e onde foram para imediata correção.

7-secondTest-Password-2

 

[/vc_column_text][us_cta title=”Interesse em TDD?” title_size=”h3″ color=”custom” bg_color=”#422b72″ text_color=”#ffffff” btn_link=”url:https%3A%2F%2Ftddcomphp.com.br||target:%20_blank|” btn_label=”Conheça meu livro” btn_size=”20px” btn_style=”4″]

Então meu livro é perfeito pra você!

Pra ficar melhor ainda, tenho um cupom de 15% de desconto. Clique em “Conheça meu livro” e pegue o seu![/us_cta][vc_column_text]

Coverage

Com o xdebug instalado temos um ótimo debugger e unindo-o ao PHPUnit podemos visualizar quanto de nosso código está coberto por testes, isto veremos agora. Primeiramente esclareço que somente podemos gerar o code coverage se a classe de testes estiver separada da classe que está sendo testada então crie um novo arquivo chamado User.php, copie toda a classe User que atualmente encontra-se no arquivo  UserTest.php e cole-o no arquivo recém criado.

 

8-newUserClass-1

Agora inclua o arquivo User.php no UserTest.php. Como neste exemplo não estamos seguindo o padrão PSR-0, não há auto loader com isso vamos no require_one() mesmo.

8-newUserClass-2

Ok, aparentemente está tudo ok, se rodarmos o phpunit com as classes em arquivos separados todos os testes devem passar assim como já passaram anteriormente. Novamente o comando $ phpunit –colors UserTest.

8-newUserClass-2

Legal, agora que em arquivos separados todos os testes permaneceram funcionando basta que geramos o code coverage dos mesmos, para isto o phpunit nos oferece diversas formas de saída para que possamos analisar, pode ser um xml, html, php ou um txt. Utilizaremos o formato html.

Digitando o comando $ phpunit –colors –coverage-html coverage UserTest temos

  • phpunit – o próprio framework de testes
  • –colors – saída com coloração para melhor
  • –coverage-html – o formato que será a saída gerada
  • coverage – pasta de destino para os arquivos hml
  • UserTest – a classe de testes.

 

Note na imagem abaixo que ao rodar o comando especificando o coverage cria-se um diretório chamado coverage conforme definimos e dentro dele diversos arquivos, era exatamente isto que desejávamos.

9-coverage-1

 

Agora entrando no browser na pasta do projeto em que estamos realizando nossos testes é necessário entrar na pasta /coveage. Ao entrar o resultado será como abaixo.

9-coverage-2

 

Neste exemplo temos apenas 1 classe testada, caso tivéssemos mais, as mesmas também seriam listadas como na imagem acima. Para visualizar detalhes da cobertura por testes basta que se clique no arquivo desejado.

9-coverage-3

O mais legal de tudo é que no próprio coverage você encontra informações para suas dúvidas como a coloração das linhas e abrangência do teste.

 

Este foi um post muito breve do que vem a ser trabalhar com desenvolvimento orientado a testes mas como o intuito é: ser uma porta de entrada para o TDD em PHP acredito ser válido até mesmo porque muita gente acha que é um bicho de 7 cabeças criar testes. Não, criar testes como pode ser visto ao longo do post é uma tarefa muito simples, o grande problema é: O QUE TESTAR?

 

Espero ter contribuído de alguma forma, até a próxima 😉

Código-fonte (PHP)

Código-fonte (Ruby)

 

[/vc_column_text][us_cta title=”Interesse em TDD?” title_size=”h3″ color=”custom” bg_color=”#422b72″ text_color=”#ffffff” btn_link=”url:https%3A%2F%2Ftddcomphp.com.br||target:%20_blank|” btn_label=”Conheça meu livro” btn_size=”20px” btn_style=”4″]

Então meu livro é perfeito pra você!

Pra ficar melhor ainda, tenho um cupom de 15% de desconto. Clique em “Conheça meu livro” e pegue o seu![/us_cta][/vc_column][/vc_row]


Andre Cardoso

Pai do Gab e da Mel, desenvolvedor PHP, co-autor do livro TDD com PHP (www.tddcomphp.com.br) e palestrante. Apaixonado por código de qualidade e resultados fantásticos.