Testes no Laravel com Pest 5 em 2026: TIA, Mocking e Perguntas de Entrevista
Domine as melhores praticas de testes no Laravel com Pest 5, Test Impact Analysis, Mockery, fakes de facades e testes de arquitetura. Aborda testes unitarios, testes de feature, estrategias de mocking e perguntas comuns de entrevistas para desenvolvedores Laravel.

As melhores praticas de testes no Laravel mudaram significativamente com o Pest 5, o motor TIA (Test Impact Analysis) e o PHPUnit 13. O Laravel 13 oferece suporte de primeira classe ao Pest, tornando a experiencia de testes mais expressiva e menos verbosa do que o PHPUnit puro. Este guia aborda os padroes que importam tanto para aplicacoes de producao quanto para entrevistas tecnicas.
O Pest 5 (construido sobre o PHPUnit 13) e o framework de testes padrao do Laravel 13. Ele requer PHP 8.4+ e introduz o motor TIA, verificacao de agentes IA nativa, integracao com PHPStan e sharding balanceado por tempo de execucao.
Configurando o Pest 5 em um Projeto Laravel 13
Cada nova aplicacao Laravel 13 instala o Pest automaticamente. Para projetos existentes, a migracao do Pest 4 leva minutos, ja que a compatibilidade com o PHPUnit 13 e a principal consideracao. A configuracao reside em tests/Pest.php, onde os traits globais e os metodos helpers sao registrados.
use Illuminate\Foundation\Testing\RefreshDatabase;
pest()
->extend(Tests\TestCase::class)
->use(RefreshDatabase::class)
->in('Feature');Este arquivo unico substitui o antigo trait CreatesApplication e a heranca de classe base. O trait RefreshDatabase envolve cada teste em uma transacao de banco de dados, revertendo as alteracoes automaticamente.
use App\Models\User;
it('registers a new user with valid data', function () {
$response = $this->postJson('/api/register', [
'name' => 'Jane Doe',
'email' => 'jane@example.com',
'password' => 'SecurePass123!',
'password_confirmation' => 'SecurePass123!',
]);
$response->assertStatus(201)
->assertJsonStructure(['user' => ['id', 'name', 'email']]);
expect(User::where('email', 'jane@example.com')->exists())->toBeTrue();
});A API expect() do Pest se encadeia naturalmente com as assertions do PHPUnit. A chamada assertJsonStructure valida o formato da resposta, enquanto expect()->toBeTrue() confirma o estado do banco de dados. Ambos os estilos coexistem sem conflito.
Test Impact Analysis: A Funcionalidade Principal do Pest 5
O motor TIA e o que torna o Pest 5 transformador para bases de codigo grandes. Na primeira execucao, o Pest registra quais testes tocam quais arquivos. Cada execucao subsequente executa apenas os testes afetados pelas suas alteracoes e reproduz os resultados em cache para todo o resto.
# First run: records baseline (requires PCOV or Xdebug)
php artisan test
# Subsequent runs: only affected tests execute
php artisan testA suite de testes do Laravel Cloud, contendo mais de 19.000 testes, caiu de aproximadamente tres minutos para cinco segundos com o TIA habilitado. O motor entende mais do que arquivos PHP: ele detecta alteracoes em migrations, templates Blade e componentes JavaScript compartilhados.
O TIA requer um driver de cobertura (PCOV ou Xdebug) para registrar a linha de base. Para pipelines de CI, os mapeamentos em cache persistem entre execucoes, tornando o ganho de desempenho cumulativo.
Testes Unitarios vs Testes de Feature no Laravel
A distincao entre testes unitarios e testes de feature no Laravel determina quais partes do framework sao inicializadas. Os testes unitarios rodam sem o container da aplicacao, tornando-os mais rapidos, mas limitados a logica pura. Os testes de feature inicializam a aplicacao completa, habilitando chamadas HTTP, consultas ao banco de dados e resolucao de servicos.
use App\Services\PriceCalculator;
describe('PriceCalculator', function () {
it('applies a percentage discount correctly', function () {
$calculator = new PriceCalculator();
// 20% off a 150.00 base price
$result = $calculator->applyDiscount(150.00, 20);
expect($result)->toBe(120.00);
});
it('rejects negative discount values', function () {
$calculator = new PriceCalculator();
expect(fn () => $calculator->applyDiscount(100.00, -5))
->toThrow(InvalidArgumentException::class);
});
});Os testes unitarios visam classes isoladas sem dependencias externas. O bloco describe agrupa assertions relacionadas, e o Pest 5 suporta blocos describe aninhados para hierarquias de testes complexas.
Os testes de feature devem representar a maioria de uma suite de testes Laravel. Eles capturam bugs de integracao que os testes unitarios nao detectam, como middleware de rota incorreto, regras de validacao ausentes ou relacionamentos Eloquent quebrados. Uma regra comum: se o codigo toca o banco de dados, a camada HTTP ou uma facade, escreva um teste de feature.
Estrategias de Mocking com Facades e Mockery
O mocking em testes Laravel isola o codigo em teste das dependencias externas. As facades do Laravel fornecem implementacoes fake integradas para filas, eventos, notificacoes, e-mail e storage. O Mockery lida com todo o resto.
use App\Models\Order;
use App\Models\User;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Queue;
use App\Mail\OrderConfirmation;
use App\Jobs\ProcessPayment;
it('dispatches payment job and sends confirmation email', function () {
// Fake both Mail and Queue facades
Mail::fake();
Queue::fake();
$user = User::factory()->create();
$order = Order::factory()->for($user)->create([
'total' => 99.99,
'status' => 'pending',
]);
// Act: confirm the order via HTTP
$this->actingAs($user)
->postJson("/api/orders/{$order->id}/confirm")
->assertOk();
// Assert: payment job was dispatched with correct amount
Queue::assertPushed(ProcessPayment::class, function ($job) use ($order) {
return $job->order->id === $order->id
&& $job->order->total === 99.99;
});
// Assert: confirmation email was sent to the user
Mail::assertSent(OrderConfirmation::class, function ($mail) use ($user) {
return $mail->hasTo($user->email);
});
});Os fakes de facades interceptam chamadas no nivel do framework, evitando que e-mails reais sejam enviados ou que jobs sejam despachados. As assertions baseadas em closures verificam os dados exatos passados para cada componente.
Evite mockar classes de dominio internas. Mocke nos limites: APIs de terceiros, e-mail, filas, sistemas de arquivos. O excesso de mocking torna os testes frageis e fortemente acoplados aos detalhes de implementacao.
Para dependencias que nao sao facades, injete-as via construtor e use o Mockery:
use App\Services\PaymentGateway;
use App\Services\StripeClient;
it('charges the customer through the payment gateway', function () {
// Create a mock of the Stripe client
$stripeClient = Mockery::mock(StripeClient::class);
$stripeClient->shouldReceive('charge')
->once()
->with('cus_abc123', 5000, 'usd')
->andReturn(['status' => 'succeeded', 'id' => 'ch_xyz']);
// Bind the mock in the container
$this->app->instance(StripeClient::class, $stripeClient);
$gateway = app(PaymentGateway::class);
$result = $gateway->processCharge('cus_abc123', 50.00);
expect($result['status'])->toBe('succeeded');
});Vincular o mock com $this->app->instance() substitui a implementacao real pela duracao do teste. O Mockery verifica que charge foi chamado exatamente uma vez com os argumentos esperados.
Testes de Arquitetura com Presets do Pest
O Pest 5 inclui testes de arquitetura que impoe regras estruturais em toda a base de codigo. Esses testes rodam contra a AST, nao em runtime, tornando-os extremamente rapidos.
arch('controllers do not use Eloquent directly')
->expect('App\Http\Controllers')
->not->toUse('Illuminate\Database\Eloquent');
arch('services are final classes')
->expect('App\Services')
->toBeFinal();
arch('no debugging functions in production code')
->expect(['dd', 'dump', 'var_dump', 'ray'])
->not->toBeUsed();A primeira regra impede que os controllers consultem o banco de dados diretamente, impondo um padrao de camada de servico. A segunda garante que os servicos nao possam ser estendidos, reduzindo a complexidade de heranca. A terceira detecta instrucoes de debug esquecidas antes que cheguem a producao.
Presets especificos para Laravel tambem estao disponiveis:
arch()->preset()->laravel();
arch()->preset()->security();
arch()->preset()->php();Essas tres linhas impoe dezenas de regras: os models estendem a classe base correta, os controllers nao contem logica de negocios, nao ha funcoes inseguras como eval() ou md5() para hashing, e as convencoes padrao do PHP sao seguidas.
Pronto para mandar bem nas entrevistas de Laravel?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Mutation Testing para Verificar a Qualidade dos Testes
A cobertura de codigo mede quais linhas sao executadas durante os testes. O mutation testing vai alem: ele modifica o codigo fonte e verifica se os testes detectam a alteracao. Se uma mutacao sobrevive, a suite de testes tem uma lacuna.
# Run mutation testing on a specific class
php artisan test --mutate --class=App\\Services\\PriceCalculatorO Pest 5 introduz mutacoes como mudar > para >=, remover instrucoes return e inverter condicoes booleanas. Um score de mutacao abaixo de 80% geralmente indica que os testes verificam saidas sem checar casos limite.
// Example: this test has high coverage but low mutation score
it('calculates shipping cost', function () {
$cost = calculateShipping(weight: 5.0, zone: 'domestic');
// Only checks that the result is numeric
expect($cost)->toBeFloat();
});
// Improved: catches mutations by asserting the exact value
it('calculates domestic shipping for 5kg package', function () {
$cost = calculateShipping(weight: 5.0, zone: 'domestic');
// Exact assertion catches operator and value mutations
expect($cost)->toBe(12.50);
});O primeiro teste passa mesmo se a logica de calculo estiver completamente errada, desde que retorne um float. O segundo teste falha imediatamente quando uma mutacao altera a formula. Assertions especificas produzem scores de mutacao mais altos.
Padroes de Testes de Banco de Dados e Factories
As model factories do Laravel geram dados de teste realistas sem construcao manual de arrays. O Pest 5 combinado com factories produz um setup de dados legivel e sustentavel.
use App\Models\Article;
use App\Models\User;
it('publishes a draft article and updates the timestamp', function () {
$author = User::factory()->create(['role' => 'editor']);
$article = Article::factory()
->for($author, 'author')
->draft()
->create(['title' => 'Testing Best Practices']);
$this->actingAs($author)
->patchJson("/api/articles/{$article->id}/publish")
->assertOk()
->assertJsonPath('data.status', 'published');
$article->refresh();
expect($article->status)->toBe('published')
->and($article->published_at)->not->toBeNull()
->and($article->published_at->isToday())->toBeTrue();
});O estado de factory draft() define valores padrao para artigos nao publicados. As assertions expect() encadeadas com ->and() se leem como linguagem natural e falham com mensagens descritivas.
Execute php artisan test --parallel para executar testes em multiplos processos. O Laravel cria automaticamente bancos de dados de teste separados para cada processo, evitando conflitos de dados. O sharding balanceado por tempo do Pest 5 distribui os testes por tempo de execucao real em vez de quantidade, garantindo que cada shard de CI termine ao mesmo tempo.
Perguntas Comuns de Entrevista Tecnica sobre Testes no Laravel
As entrevistas tecnicas para vagas Laravel frequentemente avaliam conhecimentos de testes. Aqui estao as perguntas que aparecem com mais frequencia, junto com o que uma boa resposta deve cobrir.
Qual e a diferenca entre fake(), mock() e spy() em testes Laravel?
O fake() de facade substitui toda a facade por uma implementacao em memoria (Mail::fake, Queue::fake). mock() via Mockery define expectativas antes da execucao e falha se nao forem atendidas. spy() registra interacoes e permite assertions apos a execucao, sem definir expectativas previas. A escolha depende de se o teste precisa verificar comportamento (mock), registrar interacoes (spy) ou prevenir efeitos colaterais (fake).
Como o RefreshDatabase difere do DatabaseTransactions?
O RefreshDatabase executa as migrations uma vez e envolve cada teste em uma transacao. O DatabaseTransactions assume que o banco de dados ja tem o schema correto e apenas envolve os testes em transacoes. O RefreshDatabase e mais seguro para pipelines de CI onde o banco de dados pode nao existir. O DatabaseTransactions e mais rapido quando o schema esta garantido como atualizado.
Quando os testes de feature devem ser preferidos em relacao aos testes unitarios?
Os testes de feature devem cobrir qualquer codigo que interaja com a camada HTTP, banco de dados ou servicos do Laravel. Os testes unitarios sao reservados para funcoes puras e value objects sem dependencias do framework. Em uma aplicacao Laravel tipica, os testes de feature superam os testes unitarios em uma proporcao de aproximadamente 3:1 ou mais. Isso reflete a realidade de que a maioria do codigo Laravel esta inerentemente integrada com o framework.
Como o Test Impact Analysis melhora o desempenho do CI?
O TIA registra quais testes tocam quais arquivos fonte durante a primeira execucao. Nas execucoes seguintes, o Pest executa apenas os testes afetados por arquivos alterados e reproduz resultados em cache para testes inalterados. Suites grandes que levavam minutos podem ser concluidas em segundos. O tradeoff: o TIA requer um driver de cobertura (PCOV ou Xdebug) para construir o mapa de dependencias, e a primeira execucao leva mais tempo do que uma execucao normal.
Como o mutation testing melhora a qualidade dos testes alem da cobertura de codigo?
A cobertura de codigo mede os caminhos de execucao. Um teste pode alcancar 100% de cobertura chamando cada metodo sem afirmar nada significativo. O mutation testing modifica o codigo fonte (alterando operadores, removendo returns, invertendo booleanos) e verifica que pelo menos um teste falhe. Mutacoes que sobrevivem revelam assertions muito amplas ou ausentes. Executar php artisan test --mutate produz uma porcentagem de score de mutacao junto com a cobertura padrao.
Para mais perguntas de entrevista Laravel, o banco de questoes do SharpSkill cobre autenticacao, padroes do service container, relacionamentos Eloquent e arquitetura de filas.
Testando Respostas HTTP e Assertions JSON
Os helpers de teste HTTP do Laravel verificam codigos de status, headers, estruturas JSON e destinos de redirecionamento. Combinados com o Pest, eles formam testes de integracao concisos.
use App\Models\User;
describe('API Authentication', function () {
it('rejects unauthenticated requests with 401', function () {
$this->getJson('/api/profile')
->assertUnauthorized();
});
it('returns the authenticated user profile', function () {
$user = User::factory()->create([
'name' => 'John Doe',
'email' => 'john@example.com',
]);
$this->actingAs($user)
->getJson('/api/profile')
->assertOk()
->assertJson([
'data' => [
'name' => 'John Doe',
'email' => 'john@example.com',
],
]);
});
it('validates required fields on registration', function () {
$this->postJson('/api/register', [])
->assertUnprocessable()
->assertJsonValidationErrors(['name', 'email', 'password']);
});
});O bloco describe agrupa testes relacionados a autenticacao. Cada nome de teste descreve o comportamento esperado, nao a implementacao. O metodo assertJsonValidationErrors verifica que campos especificos tem mensagens de erro de validacao.
Fontes
- Pest 5 Released pelo Laravel News, anunciando o motor TIA, o plugin Agent e Evals
- Pest 5 Now Available, documentacao oficial com requisitos e novas funcionalidades
- What We Know About Laravel 13, cobrindo PHP Attributes, AI SDK e o lancamento de marco 2026
- PHPUnit 13 Release Announcement, detalhando novas assertions e deprecacoes
Pontos Essenciais sobre Testes no Laravel com Pest 5
- O Pest 5 com Laravel 13 elimina o boilerplate atraves de uma API de configuracao fluida, cadeias
expect()e descoberta automatica de testes - O motor TIA re-executa apenas testes afetados, reduzindo a execucao de grandes suites de minutos para segundos sem sacrificar a precisao da cobertura
- Os testes de feature devem formar o nucleo de uma suite de testes Laravel, com testes unitarios reservados para logica de negocios isolada
- Os fakes de facades (
Mail::fake(),Queue::fake()) lidam com o mocking no nivel do framework, enquanto o Mockery lida com dependencias de terceiros injetadas via container - Os testes de arquitetura impoe regras estruturais (sem Eloquent em controllers, sem funcoes de debug) sem custo de runtime
- O mutation testing com
--mutatedetecta assertions fracas que a cobertura de codigo sozinha nao detecta - Os estados de factory e as assertions encadeadas
expect()->and()mantem o setup de dados de teste legivel e as assertions especificas - Para a preparacao para entrevistas Laravel, entender mock/fake/spy, o comportamento do
RefreshDatabase, TIA e mutation testing demonstra maturidade em testes alem da simples cobertura
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.
Você saberia encontrar o bug em Laravel?
Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Escrito por
Anthony Fillion-MailletFundador da SharpSkill
Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.
Atualizado em 2 de setembro de 2026
Tags
Compartilhar
Artigos relacionados

Soluções Laravel: Padrões Avançados, Depuração e Perguntas de Entrevista 2026
Dominar soluções Laravel com padrões arquiteturais avançados, técnicas de depuração e conhecimentos essenciais para entrevistas. Classes de serviço, padrão Repository, depuração com Telescope e perguntas frequentes.

Perguntas de Entrevista sobre Laravel e PHP: As 25 Principais em 2026
As 25 perguntas mais comuns em entrevistas sobre Laravel e PHP. Eloquent ORM, middleware, artisan, filas, testes e arquitetura com respostas detalhadas e exemplos de codigo.

Laravel Livewire 3 em 2026: Aplicações Reativas e Perguntas de Entrevista
Domine Laravel Livewire 3 com este guia completo sobre componentes reativos, integração com Alpine.js, validação em tempo real e perguntas de entrevista técnica.