Introdução a testes
Nesta aula, você aprenderá a importância de testar seu código PHP, os principais tipos de testes, uma visão geral do PHPUnit e como escrever seu primeiro teste. Vamos explorar boas práticas e exercícios práticos para consolidar o conhecimento.
Testar software é uma prática essencial para garantir que seu código funcione como esperado, especialmente à medida que o projeto cresce. Nesta aula, vamos mergulhar no mundo dos testes em PHP, começando pelos conceitos fundamentais e chegando à prática com PHPUnit, a ferramenta mais utilizada no ecossistema PHP.
Você vai entender por que testar é tão importante, conhecer os diferentes tipos de testes (unitários, de integração, funcionais, etc.), e aprender a configurar e escrever seus primeiros testes com PHPUnit. Ao final, terá uma base sólida para incorporar testes em seus projetos profissionais.
Por que testar
Testar é uma forma de verificar se o código produz os resultados esperados, mas vai muito além disso. Testes bem escritos servem como documentação viva, mostram como as funções e classes devem ser usadas, e dão confiança para refatorar e adicionar novas funcionalidades sem medo de quebrar o que já funciona.
Imagine que você está desenvolvendo um sistema de e-commerce e precisa alterar a regra de cálculo de frete. Sem testes, você teria que testar manualmente todas as combinações possíveis de endereço e peso, o que é inviável. Com testes automatizados, basta executar o comando de teste e verificar se tudo continua passando. Isso economiza tempo e evita regressões.
Tipos de teste
Existem vários níveis de teste, cada um com um propósito específico. Os principais são:
- Testes unitários: verificam o funcionamento de uma unidade isolada do código, geralmente um método ou função. São rápidos e devem ser numerosos.
- Testes de integração: verificam se diferentes partes do sistema funcionam juntas, como a comunicação com um banco de dados ou uma API externa.
- Testes funcionais: testam o sistema como um todo, simulando a interação do usuário com a aplicação, muitas vezes via HTTP.
- Testes de aceitação: validam se o software atende aos requisitos de negócio, geralmente escritos em uma linguagem próxima do cliente.
Nesta aula, focaremos nos testes unitários, que são a base de uma boa estratégia de testes. Eles são mais simples de escrever e executar, e ajudam a manter a qualidade do código no nível mais baixo.
PHPUnit (visão geral)
PHPUnit é o framework de testes mais popular para PHP. Ele segue o padrão xUnit, que é uma arquitetura comum em várias linguagens. Com PHPUnit, você escreve classes de teste que estendem PHPUnit\Framework\TestCase e usa métodos de asserção para verificar se os resultados são os esperados.
Para instalar o PHPUnit, você pode usar o Composer, o gerenciador de dependências do PHP. O comando abaixo instala o PHPUnit como dependência de desenvolvimento:
composer require --dev phpunit/phpunitDepois de instalado, você pode executar os testes com o comando vendor/bin/phpunit. O PHPUnit procura por arquivos de teste em um diretório especificado (geralmente tests) e executa todos os métodos que começam com test.
Primeiro teste
Vamos criar nosso primeiro teste. Suponha que temos uma classe Calculadora com um método somar. Primeiro, criamos a classe em um arquivo src/Calculadora.php:
<?php
class Calculadora
{
public function somar(float $a, float $b): float
{
return $a + $b;
}
}Agora, criamos o teste em tests/CalculadoraTest.php. O teste deve estender PHPUnit\Framework\TestCase e conter um método público que começa com test ou anotado com @test:
<?php
use PHPUnit\Framework\TestCase;
class CalculadoraTest extends TestCase
{
public function testSomar()
{
$calc = new Calculadora();
$resultado = $calc->somar(2, 3);
$this->assertEquals(5, $resultado);
}
}Neste teste, estamos verificando que ao somar 2 e 3, o resultado é 5. O método assertEquals compara o valor esperado (5) com o valor real ($resultado). Se forem diferentes, o teste falha.
Para executar, basta rodar vendor/bin/phpunit na raiz do projeto. Se tudo estiver correto, você verá uma saída como:
PHPUnit 10.5.0 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 00:00.001, Memory: 6.00 MB
OK (1 test, 1 assertion)Boas práticas
Ao escrever testes, siga estas boas práticas:
- Escreva testes pequenos e focados em um único comportamento.
- Use nomes descritivos para os métodos de teste, explicando o que está sendo verificado.
- Evite dependências externas nos testes unitários (como banco de dados ou rede); use mocks ou stubs quando necessário.
- Mantenha os testes independentes entre si, para que possam ser executados em qualquer ordem.
- Execute os testes com frequência, de preferência após cada alteração no código.
Referências
- Documentação oficial do PHPUnit
- Manual do PHP
- Documentação do Composer
- Teste de unidade - Wikipédia
- Testes unitários em PHP - Alura
- Site oficial do PHPUnit
Exercícios
- Crie uma classe `Subtracao` com um método `subtrair` que subtrai dois números. Escreva um teste PHPUnit que verifique se `subtrair(10, 4)` retorna 6.✓ Resposta:
<?php class Subtracao { public function subtrair(float $a, float $b): float { return $a - $b; } } // tests/SubtracaoTest.php use PHPUnit\Framework\TestCase; class SubtracaoTest extends TestCase { public function testSubtrair() { $sub = new Subtracao(); $this->assertEquals(6, $sub->subtrair(10, 4)); } } - O que acontece se você esquecer de estender `PHPUnit\Framework\TestCase` em sua classe de teste? Explique.✓ Resposta: Se a classe de teste não estender `PHPUnit\Framework\TestCase`, o PHPUnit não a reconhecerá como uma classe de teste válida. Os métodos `test*` não serão executados e você receberá um aviso de que nenhum teste foi encontrado.
- Escreva um teste que verifique se uma string `"Hello"` possui comprimento 5, usando `assertSame`.✓ Resposta:
use PHPUnit\Framework\TestCase; class StringTest extends TestCase { public function testComprimento() { $this->assertSame(5, strlen("Hello")); } } - Qual a diferença entre `assertEquals` e `assertSame`? Dê um exemplo onde a diferença é relevante.✓ Resposta: `assertEquals` verifica se os valores são iguais, mas não se os tipos são idênticos. `assertSame` verifica se os valores são idênticos, ou seja, mesmo valor e mesmo tipo. Exemplo:
assertEquals(1, "1")passa, masassertSame(1, "1")falha. - Como você executaria apenas um método de teste específico em um arquivo de teste?✓ Resposta: Você pode usar a opção `--filter` para filtrar por nome do método. Exemplo:
vendor/bin/phpunit --filter testSomarexecuta apenas o método `testSomar`.