Testes em PHP: Unit, Integration, E2E — guia completo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que o teste em PHP é necessário?

Desenvolvimento em PHP não é apenas escrever código que "funciona". No desenvolvimento web moderno, a estabilidade e previsibilidade da aplicação vêm em primeiro lugar. Sem testes, qualquer alteração no código corre o risco de quebrar funcionalidades já existentes, e a busca manual por erros se transforma em uma "caça aos bugs" interminável. É aqui que os testes vêm ao resgate.

Neste artigo, vamos abordar três níveis principais de teste de aplicações PHP: Unit (unitário), Integration (integração) e E2E (ponta a ponta). Você aprenderá como eles diferem, quais ferramentas usar e como construir uma estratégia de teste eficaz para o seu projeto.



Testes Unit: a base da pirâmide

Testes Unit (unitários) são o nível de teste mais rápido e isolado. Seu objetivo é verificar o funcionamento de uma "unidade" individual (classe, método ou função) separadamente das dependências externas: banco de dados, sistema de arquivos, API.



Ferramentas para PHP

O framework mais popular é o PHPUnit. Uma alternativa mais moderna é o Pest, que oferece uma sintaxe mais concisa.



Exemplo de Teste Unit com PHPUnit

Suponha que temos uma classe calculadora simples:

<?php// src/Calculator.phpclass Calculator{    public function add(int $a, int $b): int    {        return $a + $b;    }

public function divide(int $a, int $b): float { if ($b === 0) { throw new \\InvalidArgumentException('Division by zero'); } return $a / $b; }}

O teste para ela ficará assim:

<?php// tests/Unit/CalculatorTest.phpuse PHPUnit\\Framework\\TestCase;

class CalculatorTest extends TestCase{ private Calculator $calculator;

protected function setUp(): void { $this->calculator = new Calculator(); }

public function testAddReturnsCorrectSum(): void { $result = $this->calculator->add(2, 3); $this->assertEquals(5, $result); }

public function testDivideThrowsExceptionOnZero(): void { $this->expectException(\\InvalidArgumentException::class); $this->calculator->divide(10, 0); }}

Princípios-chave dos Testes Unit:

  • Isolamento: todas as dependências externas (BD, API) são substituídas por mock (simuladores) ou stub.
  • Velocidade: são executados em milissegundos.
  • Verificam um cenário específico (um assert por teste é uma boa prática).

Execução: ./vendor/bin/phpunit tests/Unit



Testes Integration: verificando a interação

Os testes de integração vão um nível acima. Eles verificam como diferentes partes do sistema funcionam juntas: a classe com o banco de dados, o controller com o model, o serviço com uma API externa (real ou simulada).



Quando os Testes Integration são necessários?

  • Verificar a correção de consultas SQL.
  • Validar a conexão entre camadas da aplicação (ex.: Repository + Entity).
  • Testar middleware ou eventos (events).


Exemplo: testando um repository com BD real

Para testes de integração, frequentemente se usa um banco de dados de teste (SQLite em memória ou transações em PostgreSQL). Vejamos um exemplo usando PHPUnit e um trait para resetar o BD:

<?php// tests/Integration/UserRepositoryTest.phpuse PHPUnit\\Framework\\TestCase;

class UserRepositoryTest extends TestCase{ private PDO $pdo; private UserRepository $repository;

protected function setUp(): void { // Cria um SQLite in-memory para isolamento $this->pdo = new PDO('sqlite::memory:'); $this->pdo->exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)');

Blogs

Book Recommendations