Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🧪
Intermediaire 25 min Laravel

Tester Laravel avec PHPUnit

Pourquoi Tester Laravel avec PHPUnit ?

L'importance de tester un code est inégalable dans tout développement logiciel, et ce n'est pas moins vrai pour les applications basées sur le framework Laravel. En effet, une application complexe comme celle-ci nécessite une couche de sécurité supplémentaire pour s'assurer qu'elle fonctionne correctement en toutes circonstances. PHPUnit, l'un des frameworks de tests les plus populaires et robustes disponibles pour PHP, offre une solution complète pour automatiser ce processus.

Un cas d'utilisation concret est la gestion d'une application e-commerce : si vous n'avez pas de tests automatisés, il sera difficile de s'assurer que chaque fonctionnalité (ajout au panier, paiement sécurisé, etc.) fonctionne comme prévu sans intervention manuelle. Les tests permettent de vérifier automatiquement chaque partie de l'application et d'identifier les bugs dès qu'ils apparaissent.

Prerequis

  • Connaissance approfondie de Laravel
  • Connaissances en PHP avancées
  • Familiarité avec PHPUnit
  • Un environnement de développement sur votre machine (XAMPP, MAMP, WAMP)
  • Composer pour gérer les dépendances
  • Node.js et npm pour les packages tiers (si nécessaire)

Concepts fondamentaux

1. Ce qu'est un test ?

Un test est une vérification systématique d'une fonctionnalité de votre application pour s'assurer qu'elle produit le résultat attendu.

// Un simple test PHPUnit
use PHPUnit\Framework\TestCase;

class ExampleTest extends TestCase
{
    public function testBasicExample()
    {
        $this->assertEquals(2, 1 + 1);
    }
}

2. Structure d'un test de Laravel

Un test de Laravel est organisé autour de classes et méthodes spécifiques. Chaque méthode de test doit commencer par le mot-clé test.

// Un test de controller
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ExampleControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_example_function()
    {
        $response = $this->get('/example');
        $response->assertStatus(200);
        $response->assertSee('Example Content');
    }
}

3. Assertions

Les assertions sont les méthodes qui permettent de vérifier des conditions spécifiques.

// Vérification d'une valeur égale
$this->assertEquals($expected, $actual);

// Vérification d'un statut HTTP
$response->assertStatus(200);

// Vérification d'un contenu dans la réponse
$response->assertSee('Example Content');

4. Mocking

Le mocking est une technique utilisée pour simuler des objets ou des méthodes.

// Mocking un service
use App\Services\SomeService;
use Illuminate\Support\Facades\App;

public function test_service_function()
{
    $mock = \Mockery::mock(SomeService::class);
    App::instance(SomeService::class, $mock);

    $mock->shouldReceive('someMethod')->andReturn(true);

    $result = app(SomeService::class)->someMethod();

    $this->assertTrue($result);
}

Mise en pratique : Projet fil rouge

1. Création du projet

composer create-project --prefer-dist laravel/laravel task-manager "8.*"
cd task-manager
npm install
npm run dev
php artisan serve

2. Création d'un modèle et une migration

php artisan make:model Task -m

Edit database/migrations/xxxx_xx_xx_xxxxxx_create_tasks_table.php:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTasksTable extends Migration
{
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description')->nullable();
            $table->boolean('completed')->default(false);
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('tasks');
    }
}

Run migrations:

php artisan migrate

3. Création d'un contrôleur

php artisan make:controller TaskController --resource

Edit app/Http/Controllers/TaskController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Task;
use Illuminate\Http\Request;

class TaskController extends Controller
{
    public function index()
    {
        $tasks = Task::all();
        return view('tasks.index', compact('tasks'));
    }

    public function store(Request $request)
    {
        $task = new Task($request->all());
        $task->save();
        return redirect()->route('tasks.index');
    }
}

4. Création des vues

Créez les fichiers de vue dans resources/views/tasks/. Par exemple, index.blade.php:

@extends('layouts.app')

@section('content')
<h1>Tasks</h1>
<a href="route('tasks.create')" class="btn btn-primary">Create New Task</a>

<ul>
    @foreach ($tasks as $task)
        <li>$task->title</li>
    @endforeach
</ul>
@endsection

5. Création des tests

Créez un test pour le contrôleur:

php artisan make:test TaskControllerTest --unit

Edit tests/Unit/TaskControllerTest.php:

<?php

namespace Tests\Unit;

use App\Models\Task;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class TaskControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_index()
    {
        $tasks = Task::factory()->create(['title' => 'Example Task']);
        
        $response = $this->get('/tasks');
        $response->assertStatus(200);
        $response->assertSee('Example Task');
    }

    public function test_store()
    {
        $data = [
            'title' => 'New Task',
            'description' => 'This is a new task.'
        ];

        $response = $this->post('/tasks', $data);
        $response->assertRedirect('/tasks');

        $this->assertDatabaseHas('tasks', [
            'title' => 'New Task'
        ]);
    }
}

Erreurs frequentes et debugging

1. Mauvaise assertion

// ❌ Mauvais
$response->assertSee('Incorrect Content');

// ✅ Correct
$response->assertSee('Example Content');

2. Mocking incorrect

// ❌ Mauvais
$mock = \Mockery::mock(SomeService::class);
app()->instance(SomeService::class, $mock);

// ✅ Correct
$mock = \Mockery::mock(SomeService::class);
app()->instance(SomeService::class, $mock);

$mock->shouldReceive('someMethod')->andReturn(true);

3. Validation de données incorrecte

// ❌ Mauvais
$response = $this->post('/tasks', []);
$response->assertStatus(200); // Devrait être 422

// ✅ Correct
$response = $this->post('/tasks', [
    'title' => ''
]);
$response->assertStatus(422);

Pour aller plus loin

1. Tests de unité vs tests d'intégration

En savoir la différence entre les tests de unité et les tests d'intégration est crucial pour une bonne architecture de test.

2. Traitement des exceptions

Apprendre à tester le traitement des exceptions peut aider à identifier rapidement les problèmes.

3. Tests asynchrones avec Laravel

Apprendre à tester les requêtes asynchrones peut être utile si vous travaillez sur des applications front-end et back-end.

Défi pratique

Créez un test pour une fonctionnalité spécifique de votre application, par exemple, la création d'une tâche avec une description vide. Assurez-vous que le test échoue correctement lorsque les données sont incorrectes et passe lorsque les données sont valides.

Besoin d'aide sur Laravel ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment installer PHPUnit sur un projet Laravel ?
Pour installer PHPUnit sur un projet Laravel, vous pouvez utiliser la commande 'composer require --dev phpunit/phpunit ^9'.
Quelle est la structure de base d'une classe de test en Laravel avec PHPUnit ?
Une classe de test en Laravel doit hériter de 'TestCase' et contenir des méthodes publiques qui commencent par 'test_'. Par exemple : public function test_example() { $this->assertTrue(true); }
Comment exécuter les tests dans un projet Laravel ?
Vous pouvez exécuter tous les tests en utilisant la commande 'php artisan test' ou pour une classe de test spécifique, utilisez 'php artisan test --filter NomDeLaClasseTest'.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.