Founder & Lead Engineer, RAITHub
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.
| Layer | What to test | Typical tool |
|---|---|---|
| Unit | Pure logic: services, value objects, calculations, in isolation | PHPUnit or Pest |
| Feature (HTTP) | Each route: status, validation, policies and gates per role, the right data for the right user | PHPUnit / Pest with the HTTP test helpers |
| Jobs, events, notifications | Queued jobs run; events fire; notifications send the right content | Laravel's fakes (Queue, Event, Notification) |
| End-to-end | Sign-in, the core workflow, checkout, in a real browser | Laravel 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.
| Failure | How a test catches it |
|---|---|
| Missing policy on one route | Authorisation test per route and role |
| Queued job fails silently | Assert the job is dispatched, and test the job runs and retries |
| Non-idempotent webhook double-charges | Send the same callback twice; assert one charge |
| Validation passes but constraint rejects | Validation tests on edge cases, against a real database |
Buy, build or hire?
| Option | Choose this when | Watch out for |
|---|---|---|
| A tool or SaaS testing platform | You want recorded browser checks fast, with little code | Recorded tests break often and live outside your repository |
| Freelancers or crowdtesting | You need a one-off manual pass before a launch | No suite remains, and no one maintains it |
| An in-house QA hire | You release weekly and want QA on the team long-term | Needs someone who writes PHP, not only a manual tester |
| A managed QAaaS team | You want feature, unit and end-to-end tests built, gated in CI and kept current | Make 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.
Related posts
Ready to discuss your project?
Book a free 15-minute technical audit with our engineering team.