você está aqui: Home  → Coluna do Cesar Brod

De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.


Testes Ágeis em PHP - parte 3

Por Cesar Brod

Data de Publicação: 03 de Junho de 2014

Nestas alturas do campeonato seus programas já devem estar dentro do estilo padrão e o PHPCheckstyle deve rodar sem erro sobre eles, tanto na linha de comando quanto dentro do IDE NetBeans. Você já deve ter sanado sua dúvida, se é que a tinha, sobre o que são comentários no estilo docblock e, como bom observador, você viu que o NetBeans apontou dois erros (Configuration exception) relativos ao codesniffer e ao messdetector. Vamos resolvê-los e falar um pouco mais sobre isso.

Primeiro, instale o pacote php-codesniffer:

sudo apt-get install php-codesniffer

Aceite os demais pacotes oferecidos pelo processo de instalação.

No menu do NetBeans, vá para Ferramentas > Plug-ins > Plug-ins Disponíveis e clique em Nome para colocá-los em ordem alfabética. Procure por phpcsmd, selecione-o clicando na caixa do seu lado esquerdo e clique em instalar, seguindo os passos indicados pelo NetBeans.

Ainda no menu do NetBeans, vá para Ferramentas > Opções > PHP > Análise de Código > Code Sniffer. Você precisa informar o caminho para o Sniffer de código. O nome dele é phpcs. Tipicamente, clicando em Pesquisar, o NetBeans deve encontrá-lo em /usr/bin/phpcs. Repare que o Code Sniffer aceita vários padrões de estilo. Se você ainda não tem uma preferência, escolha o Zend. Clique em Aplicar e Ok.

Se tudo deu certo, na janela onde você vê o seu código-fonte, você poderá clicar com o botão da direita nela e verificar a opção Check for violations.

É claro que você pode executar o php-codesniffer diretamente da linha de comando. Para isso, basta digitar o seguinte:

phpcs --standard=ZEND /pasta/programa.php

Adeque a pasta e o nome do programa de acordo com o seu ambiente. Se você já programa em PHP, experimente rodar o php-codesniffer em seus programas antigos. Você pode especificar apenas uma pasta e o phpcs verificará todos os arquivos dentro dela.

Troque, por exemplo, o padrão (--standard) para PEAR, que é o padrão usado pelo phpcs e verifique quais os erros de estilo são apontados. No mínimo, você deve notar que o PEAR espera a indentação com múltiplos de quatro espaços (e não dois, como no ZEND). Assim, você deve ver erros desse tipo:

phpcs /pasta/
(...)
 7 | ERROR | Line indented incorrectly; expected 4 spaces, found 2
 9 | ERROR | Line indented incorrectly; expected at least 8 spaces, found 4

Isto é para dizer o seguinte: independente do número de espaços que você usará na indentação, escolha um e siga consistente com a decisão tomada em conjunto com a sua equipe.

Não reinvente a roda! Dê uma lida sobre os padrões de codificação PEAR e ZEND e escolha aquele que mais se adequa a suas preferências. Se você quer usar o padrão de codificação do Drupal, dê uma olhada nesse projeto.

Mas, conforme prometido, vamos falar sobre testes unitários com o NetBeans.

Testes unitários com o NetBeans

Respire fundo, pegue um café e tenha paciência. Caso essa seja a sua primeira vez com o NetBeans (e, acredite-me, há outros IDEs com complexidade ainda maior!) as coisas podem parecer nada ortodoxas, mas com o tempo você se acostuma. De fato, a maioria absoluta destas tarefas iniciais não precisarão ser repetidas com frequência. Aqui na Sysvale o que fizemos foi seguir estas exatas instruções que você está lendo e, ao final delas, criamos uma imagem de máquina virtual de desenvolvimento e uma distribuição Linux que podem ser usadas por nossos colaboradores. Claro que, ao final dessa série de artigos, tanto a máquina virtual quanto à distribuição estarão disponíveis para download por todos os interessados.

Fazendo o NetBeans saber do PHPUnit

Ao acessar, a partir do menu do NetBeans, Ferramentas > Opções > PHP > Frameworks e Ferramentas você verá uma janela. à esquerda, contendo as ferramentas que podem ser integradas à IDE. Você lembra que no segundo artigo dessa série você instalou o PHPUnit, então deve estar tudo certo! Infelizmente, não é assim. Ao clicar na ferramenta PHPUnit você verá que precisa da versão 3.4.0 ou superior da ferramenta.

Precisamos, então, modificar nosso arquivo composer.json para que reflita a listagem a seguir (se você ficou perdido, releia o artigo anterior):

{
  "require-dev": {
   "phpunit/phpunit":"3.7.*"
  }
}

Uma dica: sempre que você precisar rodar o composer, verifique se não há atualizações:

php composer.phar self-update

Em seguida, execute o seguinte comando:

php composer.phar update

Esse comando fará com que o composer leia novamente o arquivo composer.json, desinstale a versão anterior do PHPUnit (de fato, ele desinstalará tudo o que não está no arquivo de configuração) e instale a versão indicada pelo arquivo que você acaba de criar.

Antes de seguir adiante, vejamos se a nova versão do PHPUnit, em linha de comando, funciona. Você ainda tem seus programas de teste criados no artigo anterior, certo? Adeque os caminhos e nomes de arquivos e rode o comando a seguir.

vendor/bin/phpunit testes/teste_calculadora.php

Dica: É comum acontecer, especialmente com novos e afoitos desenvolvedores que ainda não estão acostumados a manter uma estrutura de arquivos com um certo padrão, que arquivos se percam. Há duas maneiras fáceis de encontrar os arquivos fujões:

sudo updatedb # atualiza a base de dados de nomes de arquivos
sudo locate nome_do_arquivo # localiza as correspondências de nome_do_arquivo

Os comandos acima costumam ser mais rápidos e varrem todo o sistema de arquivos. Caso você tenha uma suspeita de onde estão os arquivos perdidos (muito provavelmente em alguma pasta de sua própria área de usuário), vá para essa pasta e execute o comando find dentro dela:

cd /home/minhapasta/testes
find . -name teste_calculadora.php -print | more

Para muito mais informações sobre o comando find, visite a coleção de dicas aqui no Dicas-L.

Se você não fechou a janela de seu IDE enquanto brincava de feira de ciências, ainda deve estar em Ferramentas > Opções > PHP > Frameworks e Ferramentas, PHPUnit deve estar em destaque na janela à esquerda e, à direita, você pode preencher a informação relativa ao caminho completo do script PHPUnit. Nestas alturas do campeonato, você ja sabe como fazer isso, certo? No meu caso, a localização é a seguinte:

/home/minhapasta/vendor/bin/phpunit

Pelos poderes de Grayskull

Ainda dentro da janela de configuração do PHPUnit, na linha seguinte logo abaixo à de onde você informou o caminho para o mesmo, você deve informar, também, o caminho para o gerador do Skeleton. Saiba que isso não tem nada a ver com o castelo de Grayskull e, se você não entendeu a piadinha infame, é porque você não tem filhas com a idade das minhas.

O gerador de esqueletos auxilia você na criação de classes de teste a partir de seu código de produção e código de produção a partir de suas classes de teste. O código produzido, claro, será um esqueleto! Caberá a você completá-lo com carne e pele para que ele possa ser funcional. Veremos isso logo adiante.

Sempre que você precisar de alguma coisa para o PHP, há uma boa chance de alguém já ter chegado lá antes de você e empacotado essa coisa. Visite o Packagist e, sem muito escorço, você deve encontrar o phpunit-skeleton-generator. Na própria página do pacote você irá se deparar com uma linha que deve, cada vez mais, ser familiar para você:

require: "phpunit/phpunit-skeleton-generator": "*"

Isso mesmo! De volta ao composer.json. Modifique-o, agora, para que ele tenha o seguinte conteúdo:

{
  "require-dev": {
    "phpunit/phpunit":"3.7.*",
    "phpunit/phpunit-skeleton-generator": "*"
  }
}

Como você imagina, o passo seguinte é rodar, novamente, o composer:

php composer.phar update

Você já criou familiaridade com o processo, correto? Consegue localizar o caminho para o gerador de esqueletos? No meu caso é o seguinte:

/home/minhapasta/vendor/bin/phpunit-skelgen

Veja a nota ao final desse artigo e, depois, volte aqui se preciso.

Criando o ambiente de testes

Para começar, você já sabe! Dentro do NetBeans, crie um novo projeto usando o menu Arquivo > Novo Projeto, escolha PHP > Aplicação PHP e clique em Próximo. Siga as instruções do IDE e dê o nome de MeusTestes para seu novo projeto. No momento em que for escolher o tipo de programa, escolha um script (execução em linha de comando). Neste momento, você já pode clicar em Finalizar.

Vamos criar uma pasta onde estarão os nossos testes. Para isso, clique com o botão da direita sobre Arquivos de Código-Fonte (janela superior esquerda do IDE, dentro da ama Projetos) e escolha Novo > Pasta. Dê a ela o conveniente nome de TestesUnitarios.

Você deve ter, dentro de seus arquivos de código-fonte, um programa chamado index.php, apague-o clicando sobre ele com o botão direito do mouse e selecionando deletar.

Ainda na pasta TestesUnitarios, use o menu Arquivo > Novo Arquivo > XML > Documento XML. Dê a ele o nome configuration.xml e edite-o para que ele contenha o seguinte:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="bootstrap.php" colors="false"
convertErrorsToExceptions="true" convertNoticesToExceptions="true"
convertWarningsToExceptions="true" stopOnFailure="true"> 
</phpunit>

Estamos quase lá! Clique com o botão da direita sobre o nome de seu projeto (MeusTestes) e escolha Propriedades. Selecione Testando e adicione a pasta TestesUnitarios que você acaba de criar como um diretório de testes. Em Testando provedores, marque PHPUnit.

Ainda na janela de Propriedades do Projeto, na janela à esquerda selecione PHPUnit e, em Usar Bootstrap, selecione o arquivo que está em vendor/sebastian/version/tests/bootstrap.php (ajuste o caminho apropriadamente):

/home/minhapasta/vendor/sebastian/version/tests/bootstrap.php

Marque Usar Bootstrap para criar novos testes de unidade. Viu como as coisas começam a fazer um pouco mais de sentido? Escolha o arquivo de configuração apropriado ao marcar Usar configuração XML. No meu caso:

/home/minhapasta/MeusTestes/TestesUnitarios/configuration.xml

Finalmente, marque Executar todos os arquivos de teste usando PHPUnit. Clique em Ok.

Antes de fazer os testes com o NetBeans, certifique-se de que tudo roda na linha de comando. Em nosso caso, vamos criar o esqueleto de uma classe a partir de nosso programa testecalculadora.php que, feitos todos os ajustes de estilo, até o momento está assim:

<?php

require '../calculadora.php';
/**
* Testes unitarios da calculadora basica
*/
class TesteCalculadora extends PHPUnit_Framework_TestCase {

/**
* Teste positivo de soma
*/
public function testeSoma() {
$c = New Calculadora;
$resultado = $c->soma(4, 3);
$this->assertEquals(7, $resultado);
}

}

Abaixo, a sintaxe do programa phpunit-skelgen (mais uma vez, ajuste os caminhos para os arquivos e programas de acordo com o seu ambiente):

/home/minhapasta/vendor/bin/phpunit-skelgen generate-class --bootstrap="/home/minhapasta/vendor/sebastian/version/tests/bootstrap.php" TesteCalculadora /home/minhapasta/brod/testes/teste_calculadora.php Calculadora /home/minhapasta/brod/testes/calculadora.php

Note que a chave generate-class indica que geraremos uma classe a partir de um teste. Poderíamos fazer o contrário, usando a chave generate-test para gerar os esqueletos dos testes unitários a partir de uma classe. O arquivo calculadora.php deve ter sido gerado, com os seguintes conteúdos:

<?php
/**
* Generated by PHPUnit_SkeletonGenerator on 2014-06-02 at 17:46:46.
*/
class Calculadora
{
   /**
    * @todo Implement soma().
    */
   public function soma()
   {
       // Remove the following line when you implement this method.
       throw new RuntimeException('Not yet implemented.');
   }
}

Se isso tudo funcionou, agora você pode clicar com o botão da direita do mouse em um de seus programas e escolher Ferramentas > Criar testes.

Nota: seria bom se tivesse funcionado direitinho assim, né? Infelizmente, o NetBeans ainda não acompanhou as versões mais recentes do PHPUnit e ele tenta executar uma versão antiga do phpunit-skelgen. Se você atentou à saída do comando do NetBeans, viu que ele tentou executar o seguinte:

"/usr/bin/php" "/home/minhapasta/vendor/bin/phpunit-skelgen" "--test" "--" "Calculator" "/home/minhapasta/projeto/calculadora.php" "CalculatorTest" "/home/minhapasta/projeto/testes/calculadoraTest.php"

Quando o correto deveria ser isso:

"/usr/bin/php" "/home/minhapasta/vendor/bin/phpunit-skelgen" "generate-test" "Calculator" "/home/minhapasta/projeto/calculadora.php" "CalculatorTest" "/home/minhapasta/projeto/testes/calculadoraTest.php"

Foi o Daniel Keery quem me deu a dica para resolver esse problema, usando um wrapper em shell. Atente para cada um dos elementos da linha de comando gerada pelo NetBeans, agora numerados para a sua conveniência visual:

[1] "/usr/bin/php" 
[2] "/home/minhapasta/vendor/bin/phpunit-skelgen"
[3] "--test"
[4] "--" 
[5] "Calculator"
[6] "/home/minhapasta/projeto/calculadora.php"
[7] "CalculatorTest"
[8] "/home/minhapasta/projeto/testes/calculadoraTest.php"

Na pasta /home/minhapasta/vendor/bin/, crie um arquivo chamado phpunit-skelgen.sh com o seguinte conteúdo:

#!/bin/sh
/home/minhapasta/vendor/bin/phpunit-skelgen generate-test $5 $6 $7 $8 $9

Note que, em sua linha de comando, é como se você tivesse um componente além daqueles que serão gerados pelo NetBeans, ou seja, é como se o conjunto completo de comandos e chaves fossem acrescidos de um:

[1] /home/minhapasta/vendor/bin/phpunit-skelgen generate-test
[2] "/usr/bin/php" 
[3] "/home/minhapasta/vendor/bin/phpunit-skelgen"
[4] "--test"
[5] "--" 
[6] "Calculator"
[7] "/home/minhapasta/projeto/calculadora.php"
[8] "CalculatorTest"
[9] "/home/minhapasta/projeto/testes/calculadoraTest.php"

O comando e a chave que estão no wrapper phpunit-skelgen.sh (phpunit-skelgen generate-test) serão executados e as demais variáveis serão expandidas de acordo com a lógica acima.

Torne seu wrapper executável com o comando

chmod +x phpunit-skelgen.sh 

Essa nota foi deixada para o final pois, em algum momento, esse problema deve ser resolvido de forma menos manual. Preferi colocá-la aqui, e não usar versões antigas do PHPUnit, onde esse problema não se apresentou, justamente para que o leitor (e, claro, nossa equipe aqui na Sysvale) pudesse se beneficiar das versões mais novas dos softwares.

Para que tudo funcione, basta você alterar o caminho para o gerador de esqueletos, agora apontando para o wrapper phpunit-skelgen.sh no menu principal do NetBeans, seguindo o caminho Ferramentas > Opções > PHP > Frameworks e Ferramentas > PHPUnit.

Não descobri ainda como usar o NetBeans para criar as Classes a partir dos Testes, o que é possível através da linha de comando. Caso algum leitor tenha uma sugestão, agradeço muito. É possível usar o mesmo truque do wrapper, mas aí ele serviria apenas para uma coisa de cada vez.

E chega por hoje, certo? Mas a série continua! Ainda falta falar sobre o que deve ser testado, integração contínua, testes de aceitação e muito mais.

Leia mais:

Conheça o livro "Scrum: Guia Prático para Projetos Ágeis", de autoria de Cesar Brod

Resenha: O maior desafio desta obra é tornar-se um livro de cabeceira e referência simultaneamente. A expectativa do autor é a de que os leitores o leiam de cabo a rabo e, ao final, o guardem na biblioteca pública de sua preferência para que ele esteja ao seu alcance e ao alcance de todos os demais que, por qualquer razão, não pagaram por ele.

O livro não discute se o Scrum é um processo de engenharia, um método ágil ou um conjunto de ferramentas. O Scrum é uma atitude. Aqui você encontrará histórias sobre o Scrum e métodos ágeis, começando por suas origens, suas aplicações, sempre ilustrando com casos práticos de uso. Várias referências serão apontadas (algumas escritas pelo próprio autor, outras em parceria com Joice Käfer), muitas mais ou menos acadêmicas, para enriquecer a experiência do leitor, mas apenas como acessórios à leitura deste livro.

Em resumo, aqui você encontrará história, contextualização, aplicação, método e documentação. Não espere encontrar burocracia, chatice e opressão. Todo método deve ser divertido. Qualquer livro deve ser prazeroso. Temos plena consciência dos excelentes competidores na prateleira a seu lado, atraindo sua visão.

Downloads

»»» Saiba mais sobre esta obra «««

Sobre o autor

Cesar Brod usa Linux desde antes do kernel atingir a versão 1.0. Dissemina o uso (e usa) métodos ágeis antes deles ganharem esse nome. Ainda assim, não está extinto! Escritor, consultor, pai e avô, tem como seu princípio fundamental a liberdade ampla, total e irrestrita, em especial a do conhecimento.

Mais sobre o Cesar Brod: [ Linkedin ] | [ Twitter ] | [ Tumblr ].

Veja a relação completa dos artigos de Cesar Brod