Pular para conteúdo

Aula 19 - Testes Automatizados com Pest PHP e TDD 🧪

Objetivo Pedagógico

Objetivo: Prática de Test-Driven Development (TDD) no ecossistema PHP utilizando Pest PHP, asserções declarativas, datasets e testes de arquitetura (Arch Testing).


📑 1. Fundamentos Teóricos & Análise Técnica

O framework de testes Pest PHP transformou a cultura de testes automatizados na comunidade PHP ao introduzir uma sintaxe expressiva, minimalista e inspirada nos melhores test runners modernos (como Jest e Vitest). Construído sobre a sólida base do PHPUnit, o Pest elimina o boilerplate de classes e métodos verbosos, permitindo focar diretamente na intenção e no comportamento do código.

Recursos destacados do Pest PHP: 1. Sintaxe Funcional Fluente: Testes declarados com test('descrição', function () { ... }) ou it('comportamento esperado', function () { ... }). 2. Expect API Declarativa: Cadeia de asserções legíveis como expect($resultado)->toBeInt()->toBeGreaterThan(10). 3. Testes de Arquitetura (Arch Testing): Permite escrever testes automatizados para validar que convenções de código da equipe não sejam violadas (ex: proibir que controllers usem modelos Eloquent diretamente ou garantir que DTOs sejam sempre imutáveis).

📐 Arquitetura Conceitual & Diagrama de Fluxo

flowchart LR
    Test["Pest Test Case (it 'calculates discount')"] --> Exec["Execução Funcional"]
    Exec --> Expect["Expectations API (expect()->toBe())"]
    Expect --> Result{"Asserções Válidas?"}
    Result -->|Sim| Green["Sucesso (Pass - Verde)"]
    Result -->|Não| Red["Falha com Diff Visual Colorido"]
    style Test fill:#e1f5fe,stroke:#01579b
    style Expect fill:#fff3e0,stroke:#e65100
    style Green fill:#e8f5e9,stroke:#2e7d32
    style Red fill:#ffebee,stroke:#c62828

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Testes Mais Rápidos e Limpos: Redução drástica no número de linhas necessárias para cobrir regras de negócio. - Datasets Parametrizados: Execução de um único teste contra dezenas de combinações de entradas via ->with([...]). - Arquitetura Blindada: Validação estática de regras arquiteturais diretamente no pipeline de testes. - Integração com Laravel: Helpers nativos como getJson(), postJson(), assertDatabaseHas() perfeitamente integrados.


🛠️ 2. Implementação Prática em PHP 8.2+, Pest PHP e TDD

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// OrderTest.php (Testes de Integração e Arquitetura com Pest PHP)
<?php

use App\Models\User;
use App\Services\OrderService;
use App\Services\CreateOrderDTO;

// 1. Teste de Unidade / Integração
test('cria um pedido com status pendente com sucesso', function () {
    $user = User::factory()->create();
    $dto = new CreateOrderDTO(userId: $user->id, totalAmount: 150.00, items: []);

    $service = app(OrderService::class);
    $order = $service->createOrder($dto);

    expect($order->status)->toBe('PENDING')
        ->and($order->total_amount)->toEqual(150.00)
        ->and($order->user_id)->toBe($user->id);

    $this->assertDatabaseHas('orders', [
        'id' => $order->id,
        'status' => 'PENDING'
    ]);
});

// 2. Teste de Arquitetura (Arch Testing)
test('garante que controllers não acessem modelos Eloquent diretamente')
    ->expect('App\Http\Controllers')
    ->not->toUse('App\Models');

💡 Análise Passo a Passo do Código

  1. Cadeia de Expects Fluente: expect($order->status)->toBe('PENDING')->and(...) valida múltiplas propriedades em fluxo contínuo.
  2. Validação de Banco: assertDatabaseHas confirma que a gravação física no banco relacional ocorreu corretamente.
  3. Arch Testing de Primeira Classe: A asserção de arquitetura impede violações arquiteturais e é verificada no CI.

🎯 3. Próximos Passos & Sequência Didática