Tests en Go : unit, intégration, e2e — guide complet

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Pourquoi les tests en Go sont essentiels



Go (Golang) a été conçu avec la simplicité et la fiabilité en tête. Le package intégré testing est l'un des meilleurs outils pour écrire des tests parmi les langages modernes. Il ne nécessite pas de bibliothèques tierces pour les scénarios de base, tout en étant facilement extensible. Dans cet article, nous allons aborder trois niveaux de tests : unit, intégration et e2e. Vous apprendrez comment les écrire, quand les utiliser et quels outils employer. Ce contenu sera utile aussi bien aux débutants qu'aux développeurs Go expérimentés.



1. Tests unitaires en Go : les bases fondamentales



Les tests unitaires vérifient des fonctions ou méthodes individuelles de manière isolée. En Go, il suffit de créer un fichier avec le suffixe _test.go et d'écrire des fonctions de la forme TestXxx(t *testing.T).



Exemple simple de test unitaire



Supposons que nous ayons une fonction d'addition :



// math.gopackage main

func Add(a, b int) int { return a + b}


Son test :



// math_test.gopackage main

import "testing"

func TestAdd(t *testing.T) { result := Add(2, 3) expected := 5 if result != expected { t.Errorf("Add(2, 3) = %d; want %d", result, expected) }}


Tests table-driven (Table-Driven Tests)



La communauté Go recommande d'utiliser des tests table-driven pour vérifier plusieurs cas :



func TestAddTable(t *testing.T) {    tests := []struct {        name string        a, b int        want int    }{        {"positive", 2, 3, 5},        {"negative", -1, -2, -3},        {"zero", 0, 0, 0},    }    for _, tt := range tests {        t.Run(tt.name, func(t *testing.T) {            if got := Add(tt.a, tt.b); got != tt.want {                t.Errorf("Add() = %d, want %d", got, tt.want)            }        })    }}


Les tests unitaires se lancent avec la commande :



go test ./...


2. Tests d'intégration : vérifier les interactions



Les tests d'intégration vérifient comment différentes parties du système fonctionnent ensemble : base de données, API, système de fichiers. En Go, on les place généralement dans des fichiers séparés avec une balise de compilation ou dans un package integration.



Utilisation des build tags



Créez un fichier integration_test.go avec la balise :



//go:build integration

package integration

import ( "database/sql" "testing" _ "github.com/lib/pq")

func TestDatabaseConnection(t *testing.T) { dsn := "host=localhost port=5432 user=test dbname=test sslmode=disable" db, err := sql.Open("postgres", dsn) if err != nil { t.Fatalf("Failed to open DB: %v", err) } defer db.Close()

err = db.Ping() if err != nil { t.Fatalf("Failed to ping DB: %v", err) }}


Exécution uniquement des tests d'intégration :



go test -tags=integration ./...


Travailler avec une base de données de test



Pour les tests d'intégration, on utilise souvent testcontainers-go ou une base de données en mémoire (ex. SQLite). Exemple avec testcontainers :



func TestWithPostgresContainer(t *testing.T) {    ctx := context.Background()    pgContainer, err := postgres.RunContainer(ctx,        testcontainers.WithImage("postgres:15"),        postgres.WithDatabase("testdb"),    )    require.NoError(t, err)    defer pgContainer.Terminate(ctx)

dsn, _ := pgContainer.ConnectionString(ctx) // utiliser dsn pour la connexion}


3. Tests E2E : vérifier le système dans son ensemble



Les tests End-to-End simulent le comportement de l'utilisateur et vérifient l'ensemble du système du début à la fin. En Go, ils sont souvent écrits pour les services HTTP en utilisant le package net/http/httptest.



Exemple de test E2E pour une API REST



func TestCreateUserE2E(t *testing.T) {    // Z                

Blogs

Book Recommendations