Back to BlogQuality & Testing

Test My Laravel App: Feature Tests, Pest and the Flows That Break

Rupak Amin

Founder & Lead Engineer, RAITHub

8 min read

RAITHub ships and tests production software. See QA as a Service or talk to us.

Testing a Laravel app means mostly feature tests: requests sent through the real application over HTTP, checking status, response, validation and who is allowed to do what, against a fresh test database. Add unit tests for the pure logic beneath, and a small browser suite for the journeys that matter. Use PHPUnit or Pest. An outside QA team can do this whether or not they built the app.

If you would rather have the suite built and run for you, see how RAITHub would test this near the end. RAITHub tests apps in these stacks; testing a framework does not require having built in it.

What should a Laravel test suite cover?

Laravel splits tests into feature and unit, and feature tests carry most of the weight because they exercise the framework the way a request does: routing, middleware, validation, controllers, policies and the database together (Laravel testing docs). Unit tests cover isolated logic. The authorisation layer, Laravel's policies and gates, is where the costly bugs hide.

LayerWhat to testTypical tool
UnitPure logic: services, value objects, calculations, in isolationPHPUnit or Pest
Feature (HTTP)Each route: status, validation, policies and gates per role, the right data for the right userPHPUnit / Pest with the HTTP test helpers
Jobs, events, notificationsQueued jobs run; events fire; notifications send the right contentLaravel's fakes (Queue, Event, Notification)
End-to-endSign-in, the core workflow, checkout, in a real browserLaravel Dusk, Playwright or Cypress

Most of the protection comes from feature and unit tests, which run fast. A small end-to-end set proves the whole thing holds together; that shape is the test pyramid, in the test pyramid for a SaaS.

What tools fit a Laravel app?

Laravel ships with testing built on PHPUnit and includes Pest out of the box as an alternative with a lighter syntax (Laravel testing docs). Either is a good choice; the layers you cover matter more than the framework. Laravel's HTTP test helpers send real requests to your routes in-process, so feature tests run without a live server. For the browser journeys, Laravel Dusk drives a real Chrome, and a team wanting cross-browser coverage can use Playwright; see the cross-browser testing checklist.

Use the RefreshDatabase trait so each test runs against a clean, disposable database inside a transaction that rolls back; that keeps tests independent and catches wrong queries and unenforced constraints that mocking would hide. Stub only external services, payments, email and SMS, with Laravel's fakes, and test those in sandbox mode. Payment callbacks have their own traps; see testing payments and webhooks.

What does a good Laravel feature test look like?

Act as an authenticated user and check both that the right user succeeds and that the wrong user is refused. The second half is the test that stops one user reading another's record. This Pest feature test checks the policy:

Free checklist

AI-Built App Launch Readiness Checklist

25 checks before you let real users in. Enter your email and we’ll reveal it below (and send you a copy).

One email, the checklist, no spam. By submitting you agree we can email you this checklist and reply to your enquiry.

// tests/Feature/OrderTest.php
use App\Models\User;
use App\Models\Order;

it('does not let a user view an order they do not own', function () {
    $alice = User::factory()->create();
    $bob = User::factory()->create();
    $order = Order::factory()->for($alice)->create();

    $this->actingAs($bob)
        ->get("/orders/{$order->id}")
        ->assertForbidden();
});

Write that kind of test for every route and role. Model factories build the data each test needs, and RefreshDatabase resets it afterwards, so the tests stay independent. For the full endpoint checklist, status, schema, validation, authentication, idempotency and errors, see the API testing guide.

Which Laravel flows break in production?

The expensive Laravel bugs are usually in the flows that touch money, permissions or background work. A policy that guards the index but not the show route; a queued job that fails silently and never retries; a validation rule that passes but a database constraint then rejects; a webhook handler that is not idempotent and charges twice on a retry. Feature tests and faked jobs and events catch these before a deploy does.

FailureHow a test catches it
Missing policy on one routeAuthorisation test per route and role
Queued job fails silentlyAssert the job is dispatched, and test the job runs and retries
Non-idempotent webhook double-chargesSend the same callback twice; assert one charge
Validation passes but constraint rejectsValidation tests on edge cases, against a real database

Buy, build or hire?

OptionChoose this whenWatch out for
A tool or SaaS testing platformYou want recorded browser checks fast, with little codeRecorded tests break often and live outside your repository
Freelancers or crowdtestingYou need a one-off manual pass before a launchNo suite remains, and no one maintains it
An in-house QA hireYou release weekly and want QA on the team long-termNeeds someone who writes PHP, not only a manual tester
A managed QAaaS teamYou want feature, unit and end-to-end tests built, gated in CI and kept currentMake sure the tests live in your repository and you own them

Why RAITHub for testing a Laravel app?

RAITHub tests apps in these stacks whether or not it built them, and the QA method does not change with the framework: map the risk, test the money and data paths at the lowest layer that catches them, write the policy tests that stop data leaks, and gate the suite in CI. The test counts come from real repositories, 400+ on this site, 750+ on TheSkinProof (the founder's own venture) across 217 endpoints, 530+ on Sundor Skin across 88 permission codes; how that discipline works is in QA-first development: how RAITHub tests.

When you don't need RAITHub: if you want an engineer placed inside your team under your management, that is staff augmentation, which RAITHub does not offer; and a prototype you reshape weekly may only need a short manual pass. For a framework RAITHub builds in natively, see testing a Node/Express API, which shares the same method.

How RAITHub would test this

Through QA and test automation, part of QA as a service, RAITHub would:

  • map your routes, policies and roles, and rank the money and data paths by cost of failure
  • write feature tests over HTTP with an authorisation matrix per role, and unit tests for the logic beneath
  • cover queued jobs, events and notifications with Laravel's fakes, and add a small browser set for the journeys that matter
  • wire the suite into your CI so a failing change blocks the release, with tests and configuration in your repository

Buy it as a monthly QA plan, a fixed-price one-off audit, or a dedicated QA team that RAITHub manages and bills monthly. Testers are never placed under your management. You own the tests and the IP, and an NDA is signed first. Start with a free 15-minute call, then a written fixed quote. Talk to RAITHub about testing your Laravel app.

Frequently asked questions

How do I test a Laravel app?

Write feature tests that send real requests through the app over HTTP, checking status, validation and policies per role, add unit tests for pure logic, cover queued jobs and notifications with fakes, and add a small browser suite for key journeys, all against a fresh test database in CI.

Should I use PHPUnit or Pest?

Either. Laravel ships with PHPUnit and includes Pest out of the box as a lighter-syntax alternative. The layers you cover matter more than the framework you pick; choose one and stay consistent.

What is the difference between a feature test and a unit test in Laravel?

A feature test exercises a larger part of the app, usually a full HTTP request through routing, middleware, validation, policies and the database. A unit test checks a small, isolated piece of logic. Laravel apps lean on feature tests for most coverage.

Should Laravel tests use a real database?

Yes, a disposable test database with the RefreshDatabase trait, so each test runs clean and rolls back. That catches wrong queries and unenforced constraints. Stub only external services like payments and email at the boundary, with Laravel's fakes.

Can RAITHub test a Laravel app it did not build?

Yes. Testing an app does not require having built it. RAITHub starts with the money and data paths, writes tests that pin down current behaviour, and gates them in CI before widening coverage or changing any code.

Will I own the tests?

Yes. The tests and CI configuration live in your repository, the IP is assigned to you, and the engagement runs month-to-month, so the suite keeps protecting you after it ends.

laravel testingphpunitpestfeature testsapi testingQA as a service

Ready to discuss your project?

Book a free 15-minute technical audit with our engineering team.