All insights

Testing Strategy for Laravel Teams: Feature Tests First

Feature tests exercise your application the way users do, which makes them the best first investment for most Laravel teams. Here is how to structure and run them well.

By Amir Nassar4 min read
Table of contents

Teams skip tests for understandable reasons: deadlines, uncertainty about what to test, and the feeling that tests slow everything down. The cost shows up later, when every release is stressful and nobody dares to refactor. For Laravel applications we recommend a simple strategy: write feature tests first, add unit tests where logic is complex, and keep the whole suite fast enough to run on every change. This article explains why and how.

Why feature tests first

A feature test sends a real request through your application, including routing, middleware, validation, authorization, database and response. It checks what users and clients care about: when I submit this form, the record is created, the right person is notified, and the response is correct.

That gives you three advantages over testing only small units. They catch integration mistakes, such as a route missing authentication or a validation rule that does not match the database. They survive refactoring, because they test behaviour rather than internal structure. And they double as documentation of what the system is supposed to do.

What to test first

The paths that earn or lose money

Start with checkout, booking, invoicing, payments, sign-up and any workflow where a bug has a direct business cost. Cover the happy path and the failures that matter: invalid input, expired links, insufficient stock, declined payments.

Authorization and tenant isolation

Write tests that prove one user cannot see or change another user's records, and that guests are redirected from private pages. For multi-tenant products, create two tenants and assert that data never crosses between them. These tests are short and prevent the most embarrassing incidents.

Every bug you fix

When a bug is reported, write a failing test that reproduces it, fix the code, and keep the test. Over time your suite grows exactly where your application is fragile.

Structure tests so they stay readable

A good test has three parts: arrange the data, act by calling the endpoint, and assert on the outcome. Name tests after behaviour, such as test_guest_cannot_view_invoice, so a failure tells you what broke.

public function test_customer_can_cancel_own_booking(): void
{
    $booking = Booking::factory()->create();

    $this->actingAs($booking->customer)
        ->post(route('bookings.cancel', $booking))
        ->assertRedirect();

    $this->assertSame('cancelled', $booking->fresh()->status);
}

Use factories for data

Model factories create realistic records with one line, and states such as published, draft or overdue make intent obvious. Keep factories close to valid production data, so tests fail for the right reasons.

Fake what you do not own

Laravel can fake mail, notifications, queues, events, storage and HTTP calls. Use these fakes so tests never send real emails or call real payment services, then assert that the right message or job was dispatched. Test the integration boundary itself separately, with recorded or simulated responses.

Where unit tests help

Use unit tests for pure logic with many branches: price calculations, tax rules, discount engines, date and schedule computations, parsers and formatters. These run in milliseconds and pinpoint failures precisely. Do not mock everything to unit test a controller; a feature test is clearer and more reliable.

Keep the suite fast and trusted

  1. Use an in-memory or dedicated test database and refresh it using Laravel's testing traits. Lazy refresh helps when many tests do not touch the database.
  2. Run tests in parallel when the suite grows past a minute or two.
  3. Fix or delete flaky tests quickly. A suite nobody trusts is ignored.
  4. Run on every pull request through continuous integration, and block merges when tests fail.
  5. Run a focused subset locally, filtering by file or name, and the full suite before release.

Add browser and front-end tests selectively

For applications built with Inertia and React, such as our Earth Movers ERP and Narmar Express Shipping Platform, server-side feature tests can assert on the page component and its props, which covers a large share of risk without a browser. Reserve end-to-end browser tests for a few critical journeys, because they are slower and more brittle.

How much is enough?

Chasing a coverage percentage encourages shallow tests. Instead, ask whether the tests would catch the mistakes that hurt you most. A team that can deploy on a Thursday afternoon without anxiety has enough tests. A team that avoids touching certain files does not.

Start tomorrow

If your project has no tests, do not stop to write hundreds. Add a feature test for the next bug you fix and for the next feature you build, and add a handful for authentication and your most valuable workflow. Within a few months the habit becomes part of delivery.

At Narmar we treat tests as part of the deliverable, not an extra. If you want help introducing a testing strategy to your Laravel project, or taking over an application that lacks one, see our services or contact the team.

Share this article

Planning something similar?

Tell us about your project — we reply within one business day with next steps and an honest estimate.

Talk to our engineers

Get the next insight in your inbox

Practical notes on software, AI and ERP for growing businesses. No spam — unsubscribe in one click.

  • Laravel
  • Backend
  • Security

Securing a Laravel Application: A Practical Checklist

Laravel ships with strong defaults, but secure applications still need good habits. Use this checklist to review authentication, access control, uploads, secrets and deployment.

4 min read