Laravel 12: Understanding and Implementing Test-Driven Development (TDD)

Author

Kritim Yantra

Mar 27, 2025

Laravel 12: Understanding and Implementing Test-Driven Development (TDD)

Test-Driven Development (TDD) is a powerful approach to writing clean, maintainable, and bug-free code. In this blog, we'll explore how to use TDD in Laravel 12 with simple explanations and practical examples.


What is TDD?

TDD stands for Test-Driven Development, which means:

  1. Write a failing test before writing the actual code.
  2. Write the minimal code to pass the test.
  3. Refactor the code while keeping tests green.

This cycle is called "Red-Green-Refactor".


Why Use TDD in Laravel?

✅ Ensures code reliability
✅ Reduces bugs in production
✅ Makes refactoring easier
✅ Improves code design


Setting Up Laravel 12 for TDD

First, install Laravel:

composer create-project laravel/laravel laravel-tdd-example
cd laravel-tdd-example

Laravel includes PHPUnit for testing. Check if tests run:

php artisan test

Example: Building a Simple Task Manager with TDD

Step 1: Define a Feature Test (Red Phase)

We want to create a task. Let's write a test first.

Create a test file:

php artisan make:test TaskTest

Now, write the test in tests/Feature/TaskTest.php:

<?php

namespace Tests\Feature;

use Tests\TestCase;

class TaskTest extends TestCase
{
    /** @test */
    public function a_user_can_create_a_task()
    {
        // 1. Define the data
        $taskData = ['title' => 'Learn TDD', 'description' => 'Write tests first!'];

        // 2. Send a POST request to /tasks
        $response = $this->post('/tasks', $taskData);

        // 3. Assert that the task was created
        $response->assertStatus(201);
        $this->assertDatabaseHas('tasks', $taskData);
    }
}

Run the test (it will fail - Red Phase):

php artisan test

Step 2: Write the Minimum Code to Pass (Green Phase)

1. Create a Migration

php artisan make:migration create_tasks_table

Update the migration:

public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('description');
        $table->timestamps();
    });
}

Run the migration:

php artisan migrate

2. Create a Model

php artisan make:model Task

3. Add Fillable Fields

In app/Models/Task.php:

protected $fillable = ['title', 'description'];

4. Create a Route & Controller

php artisan make:controller TaskController --invokable

Add a route in routes/web.php:

use App\Http\Controllers\TaskController;

Route::post('/tasks', TaskController::class);

5. Implement the Controller Logic

In app/Http/Controllers/TaskController.php:

public function __invoke(Request $request)
{
    $task = Task::create($request->all());
    return response()->json($task, 201);
}

Now, run the test again (Green Phase):

php artisan test

Test passes!


Step 3: Refactor (Optional)

  • Move validation logic to a Form Request
  • Extract business logic to a Service Class

Example:

php artisan make:request StoreTaskRequest

Update StoreTaskRequest:

public function rules()
{
    return [
        'title' => 'required|string|max:255',
        'description' => 'required|string',
    ];
}

Update the controller:

public function __invoke(StoreTaskRequest $request)
{
    $task = Task::create($request->validated());
    return response()->json($task, 201);
}

Run tests again to ensure they still pass.


Bonus: Writing Unit Tests

Unit tests focus on small parts of code (e.g., a single method).

Example: Testing a Task model method.

  1. Create a test:
php artisan make:test TaskUnitTest --unit
  1. Write a test in tests/Unit/TaskUnitTest.php:
public function test_task_can_be_marked_as_completed()
{
    $task = Task::factory()->create(['completed' => false]);

    $task->markAsCompleted();

    $this->assertTrue($task->completed);
}
  1. Add the method in Task model:
public function markAsCompleted()
{
    $this->update(['completed' => true]);
}
  1. Run the test:
php artisan test

Conclusion

TDD in Laravel 12 is simple:

  1. Write a failing test (Red)
  2. Write minimal code to pass (Green)
  3. Refactor & repeat

This approach ensures high-quality, maintainable code.

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts

Laravel 12 Roles and Permissions Setup: Complete Guide
Kritim Yantra Kritim Yantra
Feb 28, 2025
Laravel 12 & AdminLTE Integration: Setup Your Stunning Admin Dashboard
Kritim Yantra Kritim Yantra
Feb 28, 2025
Understanding Laravel 12 Middleware
Web Development
Understanding Laravel 12 Middleware
#Laravel #Php
Kritim Yantra Kritim Yantra
Mar 05, 2025