laravelmastery
SnippetsArticlesSeriesNews

Test-driven Laravel · Lesson 1 of 3

Test-driven Laravel · Lesson 1

What a feature test is for

The shape of a testTesting

By the end, issuing an invoice fails the suite when the feature breaks. A feature test checks one thing a person can do, through the same door they use. For an invoice, that door is an HTTP request. The test does not call a private method, and it does not care which line of the controller wrote the row.

Video

01 Name it for the outcome

If the feature disappeared, this test would fail. That is the check that the test is aimed at the behaviour rather than at the framework.

PHP
it('issues an invoice for the signed-in team', function () {
    $user = User::factory()->create();

    $this->actingAs($user)
        ->post('/invoices', [
            'number' => 'INV-1042',
            'issued_on' => '2026-10-22',
        ])
        ->assertRedirect();
});

One test, one outcome. A second behaviour, such as “a guest is redirected to login”, is a second test. Mixing them makes a failure tell you less about what broke.

02 A guest is a second test

The signed-in test above never sees the login redirect. A guest test leaves actingAs() off and asserts the redirect Laravel’s auth middleware actually returns. It does not assert a saved invoice, because the interesting fact is that no invoice was written.

PHP
it('sends a guest to login', function () {
    $this->post('/invoices', [
        'number' => 'INV-1042',
        'issued_on' => '2026-10-22',
    ])->assertRedirect('/login');

    $this->assertDatabaseCount('invoices', 0);
});

If this test fails on the redirect, the route lost its middleware. If it fails on the count, the controller stored a row before the middleware ran. Those are different bugs, which is why they are not folded into the test that checks a team’s invoice number. A feature test that never makes an HTTP call is a unit test of a class. This series is about the request.

Recap

You can name a test for one outcome a person would notice, and send the HTTP request they would send.

  • One behaviour per test. A guest redirect is a second test.
  • A feature test that never makes a request is a unit test of a class.
  • The count and the redirect fail for different bugs. Keep them where the failure is readable.

Check yourself · 3 questions

Question 1 of 3The guest test and the signed-in test are one method. It fails. What do you know?

A feature test checks one thing a person would notice. Next, the three beats inside that test.

← PreviousOverview

On this page

  • Name it for the outcome
  • A guest is a second test
  • Recap
  • Check yourself

Test-driven Laravel

  • 1 Overview

The shape of a test

  • 2 What a feature test is for
  • 3 Arrange, act, assert
  • 4 Refreshing the database
  • 5 Factories that read like the domain
  • 6 Acting as a user

The paths that matter

  • 7 HTTP tests for happy paths
  • 8 Validation errors
  • 9 Authorisation

Edges and judgement

  • 10 Faking the mail
  • 11 Faking the queue
  • 12 Faking storage and HTTP
  • 13 Freezing time
  • 14 Datasets
  • 15 What not to test

Test-driven Laravel

Lessons

  1. 01Overview

The shape of a test

  1. 02What a feature test is for
  2. 03Arrange, act, assert
  3. 04Refreshing the database
  4. 05Factories that read like the domain
  5. 06Acting as a user

The paths that matter

  1. 07HTTP tests for happy paths
  2. 08Validation errors
  3. 09Authorisation

Edges and judgement

  1. 10Faking the mail
  2. 11Faking the queue
  3. 12Faking storage and HTTP
  4. 13Freezing time
  5. 14Datasets
  6. 15What not to test

Get the Friday email

One snippet and the week’s Laravel news, in your inbox every Friday morning. Unsubscribe whenever you like.

laravelmastery

Practical Laravel learning for working developers, made in the UK.

Learn

  • Snippets
  • Articles
  • Series

Stay current

  • News
  • Friday email
  • RSS feed

Company

  • About
  • Privacy
  • Terms
© 2026 Laravel Mastery. Independent and not affiliated with Laravel Holdings Inc.Designed and built by Half Shell Studios

We remember the videos you watch, where you left off, and which series lessons you mark as read, against this connection’s address. Nothing is stored until you agree.