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

Laravel Php

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Continue 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