Retour au cours

tests automatise

Objectifs

  • Comprendre pourquoi il est important de tester ses scripts shell.
  • Découvrir un framework de test simple comme bats-core.
  • Écrire un premier test qui vérifie le code de sortie et la sortie d’un script.
  • Intégrer les tests dans un processus de validation automatisé (CI).

Explications détaillées

Notions clés

Tester manuellement un script est répétitif et source d’erreurs. Les tests automatisés garantissent que votre script se comporte comme prévu et que des modifications futures ne cassent pas une fonctionnalité existante (non-régression).

bats-core : Un framework de test pour Bash

bats-core (Bash Automated Testing System) est un framework populaire qui apporte une structure de type “TAP” (Test Anything Protocol) à vos tests shell. Il permet d’écrire des tests de manière lisible et structurée.

Un fichier de test bats est un script Bash avec une syntaxe spéciale :

  • Les tests sont des fonctions préfixées par @test "description".
  • À l’intérieur, vous exécutez la commande ou le script que vous voulez tester.
  • bats fournit des variables spéciales comme $status (le code de sortie) et $output (la sortie standard) de la dernière commande exécutée avec run.

Assertions : Vérifier les résultats

Un test “réussit” si toutes ses commandes se terminent avec un code de sortie 0. On vérifie les résultats avec des conditions [[ ... ]].

  • [[ "$status" -eq 0 ]] : La commande a-t-elle réussi ?
  • [[ "$output" == "Hello" ]] : La sortie est-elle exactement “Hello” ?

Golden Files

Pour tester une sortie complexe, au lieu de la mettre en dur dans le script de test, on la stocke dans un fichier de référence (“golden file”). Le test consiste alors à comparer la sortie actuelle avec le contenu de ce fichier.

Syntaxe / Usages

# Installation de bats-core (par exemple via npm ou clonage du repo)
# npm install -g bats

# Exemple de fichier de test : test/mon_script.bats
#!/usr/bin/env bats

# 'load' permet d'inclure des fichiers de helper, comme la librairie d'assertions
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'

@test "mon_script.sh doit afficher Bonjour" {
  # 'run' exécute la commande et capture $status et $output
  run ./mon_script.sh
  assert_success # Vérifie que $status est 0
  assert_output "Bonjour"
}

@test "mon_script.sh avec un argument" {
  run ./mon_script.sh "Alice"
  assert_success
  assert_output "Bonjour, Alice"
}

# Pour lancer les tests
# bats test/

Exemples

Supposons un script calcul.sh :

#!/bin/bash
if [[ $# -ne 2 ]]; then exit 1; fi
echo $(($1 + $2))

Le fichier de test test/calcul.bats pourrait être :

#!/usr/bin/env bats
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'

@test "calcul.sh additionne 2 et 3" {
  run ./calcul.sh 2 3
  assert_success
  assert_output "5"
}

@test "calcul.sh doit échouer sans arguments" {
  run ./calcul.sh
  assert_failure # Vérifie que le code de sortie est non-nul
}

Bonnes pratiques

  • Un test par comportement. Chaque fonction @test ne doit vérifier qu’une seule chose.
  • Nommez vos tests clairement. La description doit expliquer ce que le test vérifie.
  • Intégrez les tests à votre CI/CD. Lancez bats automatiquement à chaque push ou pull request.

Pièges courants

  • Dépendances à l’environnement : Un test qui dépend d’un fichier ou d’une variable d’environnement spécifique peut échouer sur une autre machine. Utilisez des setup et teardown pour créer un environnement de test propre.
  • Sorties complexes : Tester une sortie HTML ou JSON complexe avec assert_output est fragile. Préférez les “golden files”.

Exercices

  1. Installez bats-core :

    • Suivez les instructions sur le dépôt GitHub de bats-core pour l’installer.
  2. Testez un script simple :

    • Créez un script hello.sh qui affiche “Hello World”.
    • Créez un fichier test/hello.bats qui vérifie que le script réussit et que sa sortie est bien “Hello World”.
    • Lancez bats test/.
  3. Testez les cas d’erreur :

    • Modifiez hello.sh pour qu’il prenne un nom en argument et qu’il quitte avec une erreur s’il n’y en a pas.
    • Ajoutez un test dans hello.bats qui vérifie que le script échoue (assert_failure) lorsqu’il est appelé sans argument.