Leçon 6/6 7 min

Tests et benchmarks

Testez et mesurez les performances de votre code Go : testing, table-driven tests, benchmarks.

Le package testing

Go a le testing intégré dans le langage. Pas besoin d'installer Jest, pytest ou PHPUnit. Tout est déjà là.

Règles simples :

  • Le fichier de test s'appelle *_test.go (ex : math_test.go)
  • Les fonctions de test commencent par Test (majuscule)
  • Elles prennent un paramètre *testing.T
// math.go
package math

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

// math_test.go
package math

import "testing"

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

Lancez les tests avec go test :

$ go test
PASS
ok      myproject/math  0.002s

0.002 secondes. Pas de setup, pas de configuration, pas de dépendances. Juste go test.

Table-driven tests — l'idiome Go

Les table-driven tests sont le pattern le plus utilisé en Go. Au lieu d'écrire une fonction par cas de test, vous définissez un tableau de cas :

func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positifs", 2, 3, 5},
        {"négatifs", -1, -2, -3},
        {"zéro", 0, 0, 0},
        {"mixte", -5, 10, 5},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("Add(%d, %d) = %d, attendu %d",
                    tt.a, tt.b, result, tt.expected)
            }
        })
    }
}

Chaque cas de test a un nom — quand un test échoue, vous savez immédiatement lequel. Et ajouter un nouveau cas ? Une seule ligne.

Sortie avec go test -v :

=== RUN   TestAdd
=== RUN   TestAdd/positifs
=== RUN   TestAdd/négatifs
=== RUN   TestAdd/zéro
=== RUN   TestAdd/mixte
--- PASS: TestAdd (0.00s)
PASS

Benchmarks : mesurer les performances

Go intègre aussi les benchmarks. Même fichier _test.go, mais avec Benchmark au lieu de Test :

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}

Lancez avec go test -bench=. :

$ go test -bench=.
BenchmarkAdd-8   1000000000   0.2850 ns/op
PASS

Go a exécuté la fonction 1 milliard de fois et chaque appel a pris 0.28 nanosecondes. C'est comme ça qu'on vérifie que le code est performant — avec des chiffres, pas des intuitions.

Vous pouvez aussi mesurer la mémoire avec -benchmem :

$ go test -bench=. -benchmem
BenchmarkAdd-8   1000000000   0.2850 ns/op   0 B/op   0 allocs/op

0 B/op — zéro allocation mémoire par opération. Voilà pourquoi Go est rapide.

Commandes utiles

# Lancer tous les tests
go test ./...

# Tests avec détails
go test -v ./...

# Couverture de code
go test -cover ./...

# Générer un rapport de couverture
go test -coverprofile=cover.out ./...
go tool cover -html=cover.out

# Benchmarks
go test -bench=. -benchmem ./...

go test ./... lance les tests dans tous les packages de votre projet. Le -cover vous montre quel pourcentage de votre code est couvert par les tests.

The testing package

Go has testing built into the language. No need to install Jest, pytest, or PHPUnit. Everything is already there.

Simple rules:

  • Test files are named *_test.go (e.g., math_test.go)
  • Test functions start with Test (capital T)
  • They take a *testing.T parameter
// math.go
package math

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

// math_test.go
package math

import "testing"

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

Run tests with go test:

$ go test
PASS
ok      myproject/math  0.002s

0.002 seconds. No setup, no configuration, no dependencies. Just go test.

Table-driven tests — the Go idiom

Table-driven tests are the most common pattern in Go. Instead of writing one function per test case, you define a table of cases:

func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positives", 2, 3, 5},
        {"negatives", -1, -2, -3},
        {"zeros", 0, 0, 0},
        {"mixed", -5, 10, 5},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("Add(%d, %d) = %d, expected %d",
                    tt.a, tt.b, result, tt.expected)
            }
        })
    }
}

Each test case has a name — when a test fails, you immediately know which one. And adding a new case? Just one line.

Output with go test -v:

=== RUN   TestAdd
=== RUN   TestAdd/positives
=== RUN   TestAdd/negatives
=== RUN   TestAdd/zeros
=== RUN   TestAdd/mixed
--- PASS: TestAdd (0.00s)
PASS

Benchmarks: measuring performance

Go also has built-in benchmarks. Same _test.go file, but with Benchmark instead of Test:

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}

Run with go test -bench=.:

$ go test -bench=.
BenchmarkAdd-8   1000000000   0.2850 ns/op
PASS

Go executed the function 1 billion times and each call took 0.28 nanoseconds. That's how you verify code is performant — with numbers, not intuition.

You can also measure memory with -benchmem:

$ go test -bench=. -benchmem
BenchmarkAdd-8   1000000000   0.2850 ns/op   0 B/op   0 allocs/op

0 B/op — zero memory allocations per operation. That's why Go is fast.

Useful commands

# Run all tests
go test ./...

# Tests with details
go test -v ./...

# Code coverage
go test -cover ./...

# Generate coverage report
go test -coverprofile=cover.out ./...
go tool cover -html=cover.out

# Benchmarks
go test -bench=. -benchmem ./...

go test ./... runs tests in all packages of your project. The -cover flag shows what percentage of your code is covered by tests.

Testez dans le Go Playground

Les tests fonctionnent dans le Playground ! Essayez les table-driven tests :

Avec l'IA

Copiez ce prompt dans Claude ou ChatGPT :

Écris des table-driven tests Go pour une fonction qui valide une adresse email. Teste les cas valides, invalides, vides et les cas limites. Ajoute un benchmark.
Comment s'appelle un fichier de test en Go ?
Quel est l'avantage des table-driven tests ?
Quelle commande lance les benchmarks en Go ?

Pour aller plus loin

Vous maîtrisez maintenant les fondamentaux de Go. Voici les sujets avancés à explorer ensuite :

  • Interfaces — le polymorphisme en Go, sans héritage Tour of Go
  • Generics — les types paramétrés, arrivés avec Go 1.18 Tutorial
  • Modulesgo.mod pour gérer les dépendances Tutorial
  • Gin / Echo — frameworks web populaires pour les API Gin · Echo
  • GORM — l'ORM le plus utilisé en Go gorm.io

Références complètes : Go.dev Documentation · A Tour of Go · Go by Example

Vous êtes un développeur polyvalent

Go est le langage de l'infrastructure moderne. Performant, simple, conçu pour le cloud. Avec HTML/CSS/JS pour le front, PHP ou Python pour le back, et Go pour les services haute performance, vous avez une palette complète de développeur polyvalent.

Vous n'êtes plus un débutant — vous êtes un développeur qui utilise l'IA comme un outil, pas comme une béquille.

En 6 leçons, vous avez appris les variables, les fonctions, la gestion d'erreurs, la concurrence, les API REST et les tests. Vous avez les bases pour construire des services rapides et fiables.

La suite ? Construisez quelque chose. Un CLI, une API, un microservice. Le meilleur apprentissage, c'est la pratique.

Going further

You now master Go's fundamentals. Here are advanced topics to explore next:

  • Interfaces — polymorphism in Go, without inheritance Tour of Go
  • Generics — parameterized types, introduced in Go 1.18 Tutorial
  • Modulesgo.mod for dependency management Tutorial
  • Gin / Echo — popular web frameworks for APIs Gin · Echo
  • GORM — the most popular ORM in Go gorm.io

Full references: Go.dev Documentation · A Tour of Go · Go by Example

You are a versatile developer

Go is the language of modern infrastructure. Performant, simple, designed for the cloud. With HTML/CSS/JS for the front, PHP or Python for the back, and Go for high-performance services, you have a complete versatile developer toolkit.

You're no longer a beginner — you're a developer who uses AI as a tool, not as a crutch.

In 6 lessons, you learned variables, functions, error handling, concurrency, REST APIs, and testing. You have the foundation to build fast and reliable services.

What's next? Build something. A CLI, an API, a microservice. The best learning is practice.

Besoin d'un développeur pour votre projet ?

Réponse sous 24h — Sans engagement