Passer au contenu principal
eLearner.app
Module 9 · Leçon 1 sur 541/50 dans le cours~12 min
Leçons du module (1/5)

Le package testing

Dans Go, les tests font partie de la stdlib : pas de bibliothèque externe, pas de framework à configurer. Tout ce dont vous avez besoin est un fichier *_test.go à côté du code, quelques fonctions TestXxx et la commande go test.

##Conventions de base

  • Les fichiers de test sont nommés <something>_test.go et se trouvent dans le même package que le code qu'ils testent (ou dans un package <name>_test pour les "tests en boîte noire").
  • Les fonctions de test ont une signature exacte : func TestXxx(t *testing.T)Xxx commence par une lettre majuscule.
  • Vous importez testing depuis stdlib.
  • Pas de assertEquals : vous utilisez if got != want { t.Errorf(...) } avec les verbes fmt.
Go
// math.go
package math

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

// math_test.go
package math

import "testing"

func TestSum(t *testing.T) {
    got := Sum(2, 3)
    if got != 5 {
        t.Errorf("Sum(2,3) = %d; voglio %d", got, 5)
    }
}

Exécutez-le avec :

Bash
go test ./...        # all packages in the module
go test -v ./pkg     # verbose: prints test names
go test -run TestSum  # only tests matching the regex

t.Error contre t.Fatal

Ce sont les deux verbes de base pour signaler un échec :

MéthodeEffet
t.Log(args...)Enregistre mais n'échoue pas (visible uniquement avec -v ou en cas d'échec).
t.Error(args...)Enregistre, marque FAIL, continue la fonction de test.
t.Errorf(fmt, ...)Comme Error avec formatage.
t.Fatal(args...)Enregistre, marque FAIL, arrête le test (appelle runtime.Goexit).
t.Fatalf(fmt, ...)Comme Fatal avec formatage.

Règle générale : utilisez Fatal lorsque continuer n'a aucun sens (par exemple, échec de la configuration, déréférencement imminent du pointeur nul) ; sinon Error, qui vous permet de voir tous les échecs en une seule exécution.

Go
func TestOpen(t *testing.T) {
    f, err := os.Open("fixtures/sample.txt")
    if err != nil {
        t.Fatal(err) // if it doesn't open, the next steps would fail on nil
    }
    defer f.Close()
    // ... assert on content with t.Errorf
}

Installation et démontage avec t.Cleanup

Pour libérer des ressources à la fin d'un test (ou sous-test), utilisez t.Cleanup au lieu de defer :

Go
func TestDB(t *testing.T) {
    db := newTestDB(t)
    t.Cleanup(func() { db.Close() })
    // ... test
}

L'avantage par rapport à defer : l'assistant qui crée db peut enregistrer le nettoyage en interne, les appelants n'ont donc pas besoin de s'en souvenir.

Aides aux tests

La méthode t.Helper() marque une fonction comme « assistant » : lorsqu'un test échoue, la trace de la pile ignore la fonction d'assistance et pointe directement vers l'appelant :

Go
func mustParseInt(t *testing.T, s string) int {
    t.Helper()
    n, err := strconv.Atoi(s)
    if err != nil {
        t.Fatalf("parse %q: %v", s, err)
    }
    return n
}

Exercices

Exercice#go.m9.l1.e1
Tentatives : 0Chargement…

Définissez la fonction TestSum qui vérifie Sum(2,3) == 5 en utilisant t.Errorf avec un message formaté.

Chargement de l'éditeur…

Solution disponible après 3 tentatives

Exercice#go.m9.l1.e2
Tentatives : 0Chargement…

Dans TestDiv, utilisez t.Fatal pour arrêter immédiatement le test si Div renvoie une valeur inattendue.

Chargement de l'éditeur…

Solution disponible après 3 tentatives

Quiz#go.m9.l1.e3
Prêt

Quelle est la différence fondamentale entre t.Error et t.Fatal ?

Go
if err != nil {
  t.???(err)
}
Options de réponse