menu
Adianti Framework
menu Menu
Testes unitários são testes sobre as menores unidades de um software, que na orientação a objetos são os métodos das classes. Alguns programadores pensam que, após o programa escrito e validado, não precisaria de testes, pois está funcionando. Entretanto, alterações posteriores em código-fonte, inclusive de outras partes do software, podem fazer que um método que estava funcionando, pare de retornar a informação esperada.

Imagine um software escolar que possui um método para gravar as matrículas de um aluno. Dentro deste método existe a chamada para outro, que gera as parcelas financeiras, tudo dentro da mesma transação. Perceba que, mesmo que hoje o método esteja funcionando perfeitamente, qualquer alteração subsequente por parte de outro programador no método que gera as parcelas financeiras (que fica em outra classe, mas é executado dentro do processo), pode colocar a matrícula em risco, fazendo com que ela gere resultados inconsistentes.

Este tipo de situação, em que uma unidade do software para de se comportar da maneira adequada por uma alteração indireta, é percebida eventualmente por programadores ao utilizarem o software para testes. Mas outras vezes é percebida somente pelos seus usuários ou clientes, o que convenhamos, é muito ruim para a reputação da empresa e para seu negócio.

Mas o que os testes unitários ajudam com isso? Testes unitários são testes programados de métodos, ou seja, escrevemos testes sobre nossos próprios códigos. Como o teste é um programa, podemos fazer com que ele rode com uma frequência programada, como todo dia, toda hora, ou melhor, à cada commit realizado para verificar se alguma coisa que fizemos veio a quebrar algum método do software.

Ao construirmos um software, escrevemos classes de modelo, serviços, controllers, etc. Um bom ponto de start é testarmos as classes de modelo e serviço, que possui grande potencial de reaproveitamento e utilização em vários pontos do sistema.

Neste artigo, vamos escrever testes, mas antes precisamos instalar o framework de testes PHPUnit, que já fornece uma arquitetura que favorece a escrita de testes. Para tal, você pode acessar o site da PHPUnit e seguir as instruções de instalação que podem variar conforme a versão do PHP que você possui rodando. No momento da escrita deste artigo, usei a seguinte versão:

php composer.phar require --dev phpunit/phpunit ^7


Obs: Você precisa do composer (https://getcomposer.org/) instalado para então instalar a PHPUnit. Leia nosso artigo sobre o Composer (www.adianti.com.br/forum/pt/view_4265?integrar-bibliotecas-pelo-comp).

Agora podemos escrever um teste. Cada conjunto de testes é escrito na forma de uma classe. Gravaremos esta classe na pasta app/tests. Cada classe de testes deve estender a classe TestCase da PHPUnit, e deve ter a cláusula use no início para termos acesso à classe TestCase que fica no Namespace PHPUnitFramework. No caso do Adianti Framework, podemos utilizar qualquer método do framework em um teste. Neste teste específico, estamos inicialmente excluindo todos pedidos do cliente de código 1. Em seguida, criamos um pedido para ele, vom o valor 10, bem como adicionamos um item à este pedido. Ao final, executamos o método getTotalPedidosPessoa(), passando o código do cliente, e o ano atual. O valor retornado deve ser igual à $value (10), visto que este cliente teve todos os pedidos excluídos antes de criar este novo. Neste teste, estamos verificando principalmente o método getTotalPedidosPessoa(), cuja implementação não vem ao caso, mas que retorna todos os pedidos do cliente no ano.

O método assertEquals() é um método da PHPUnit para comparar igualdade entre operandos. Neste caso, ele compara o retorno da função com a variável $value. Caso esta comparação não resultar em igualdade, o teste falhará quando executado.

app/tests/PedidoTest.php
  1. <?php
  2. use PHPUnit\Framework\TestCase;
  3. class PedidoTest extends TestCase
  4. {
  5.     public function testTotalPedidosPessoa()
  6.     {
  7.         $cliente_id 1;
  8.         $value      10;
  9.         
  10.         TTransaction::open('microerp');
  11.         $pedidos Pedido::where('cliente_id''=''1')->load();
  12.         foreach ($pedidos as $pedido)
  13.         {
  14.             $pedido->delete();
  15.         }
  16.         
  17.         $pedido = new Pedido;
  18.         $pedido->cliente_id $cliente_id;
  19.         $pedido->estado_pedido EstadoPedido::find(1);
  20.         $pedido->dt_pedido date('Y-m-d');
  21.         $pedido->valor_total $value;
  22.         $pedido->store();
  23.         
  24.         $item = new PedidoItem;
  25.         $item->pedido_id $pedido->id;
  26.         $item->produto_id 1;
  27.         $item->valor $value;
  28.         $item->store();
  29.         
  30.         $this->assertEqualsPedido::getTotalPedidosPessoa($cliente_iddate('Y')), $value );
  31.         //TTransaction::close();
  32.     }
  33. }
  34. ?>


Após termos a PHPUnit instalada, podemos executar todos os testes de uma pasta facilmente, como o comando a seguir. Para executar os testes, é necessário que o Framework tenha as suas classes carregadas. As classes do Framework são carregadas pelo arquivo init.php. A PHPUnit aceita um parâmetro de inicialização (--bootstrap), que recebe como parâmetro este arquivo de inicialização. O último parâmetro é a pasta que conterá os testes.

./vendor/bin/phpunit --bootstrap init.php app/tests/


Ao executar os testes, você terá um output com o resultado da execução:

PHPUnit 7.0.3 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 104 ms, Memory: 4.00MB OK (1 test, 1 assertion)


Neste caso, temos 1 teste, que passou sem erros.


Caso você queira gerar um output que possa ser lido e interpretado, pode gerar em outros formatos como o XML.

./vendor/bin/phpunit --bootstrap init.php app/tests/ --testdox-xml x.xml


Neste caso, o arquivo gerado terá o seguinte formato:
<tests> <test className="PedidoTest" methodName="testTotalPedidosPessoa" prettifiedClassName="Pedido" prettifiedMethodName="Total pedidos pessoa" status="0" time="0.028434038162231" size="-1" groups="default"/> </tests>


Assim, você pode fazer um parsing no output e gerar estatísticas sobre os testes.


Comentários

Alexandre E. Souza: ( 2018-09-25)
muito top, estava precisando dele :)
 


Você precisa realizar login para enviar posts, comentários, dentre outros. Para isso, clique em um dos botões a seguir para logar utilizando a API de um dos serviços.