Tests unitaires des scripts bash

Nous avons un système qui utilise des scripts bash en plus du code Java. Puisque nous essayons de tester tout ce qui pourrait éventuellement se casser, et que ces scripts bash peuvent se briser, nous voulons les tester.

Le problème est qu’il est difficile de tester les scripts bash.

Existe-t-il un moyen ou une meilleure pratique pour tester les scripts bash? Ou devrions-nous arrêter d’utiliser des scripts bash et rechercher des solutions alternatives testables?

    Il existe en fait un framework de test unitaire pour les scripts shell . Je ne l’ai pas utilisé moi-même, mais cela pourrait être intéressant.

    Des questions similaires ont été posées avant:

    • Test unitaire pour les scripts shell
    • Test du protocole Anything dans les scripts Shell

    J’ai reçu la réponse suivante d’un groupe de discussion:

    il est possible d’importer (inclure) une procédure (fonction, quelle qu’elle soit nommée) à partir d’un fichier externe. C’est la clé pour écrire un script de test: vous divisez votre script en procédures indépendantes qui peuvent ensuite être imscopes à la fois dans votre script en cours d’exécution et dans votre script de test, puis votre script en cours d’exécution est aussi simple que possible.

    Cette méthode s’apparente à l’dependency injections pour les scripts et semble raisonnable. Eviter les scripts bash et utiliser un langage plus testable et moins obscur est préférable.

    Test Bash compatible TAP : Système de test automatisé Bash

    chauve-souris

    Pourquoi dites-vous que c’est “difficile” de tester les scripts bash?

    Quel est le problème avec les wrappers de test comme:

    #!/bin/bash set -e errors=0 results=$($script_under_test $args< &1 let errors+=1 } echo "$results" | grep -q $expected1 || { echo "Test Failed. Expected $expected1" let errors+=1 } # and so on, et cetera, ad infinitum, ad nauseum [ "$errors" -gt 0 ] && { echo "There were $errors errors found" exit 1 } 

    Epoxy est un framework de test Bash que j’ai principalement conçu pour tester d’autres logiciels, mais je l’utilise également pour tester les modules bash, y compris lui – même et Carton .

    Les principaux avantages sont des frais généraux de codage relativement faibles, une imbrication des assertions illimitée et une sélection flexible des assertions à vérifier.

    J’ai fait une présentation en la comparant à BeakerLib – un framework utilisé par certains chez Red Hat.

    Essayez le bashtest . C’est un moyen simple de tester vos scripts. Par exemple, vous avez do-some-work.sh qui modifie certains fichiers de configuration. Par exemple, ajoutez une nouvelle ligne PASSWORD = 'XXXXX' au fichier de configuration /etc/my.cfg .

    Vous écrivez des commandes bash ligne par ligne, puis vérifiez le résultat.

    Installer:

     pip3 install bashtest 

    Créer des tests est une simple écriture des commandes bash.

    Fichier test-do-some-work.bashtest :

     # run the script $ ./do-some-work.sh > /dev/null # testing that the line "PASSWORD = 'XXXXX'" is in the file /etc/my.cfg $ grep -Fxq "PASSWORD = 'XXXXX'" /etc/my.cfg && echo "YES" YES 

    Exécuter des tests:

     bashtest *.bashtest 

    Vous pouvez trouver des exemples ici et ici

    Peut-être que cela peut être utilisé ou consortingbué à

    https://thorsteinssonh.github.io/bash_test_tools/

    Destiné à écrire des résultats dans le protocole TAP, que j’imagine bon pour les CI, et bon pour ceux qui veulent des environnements shell. J’imagine que certaines choses s’exécutent dans des environnements de shell, certains pourraient argumenter devraient être testés dans leur environnement shell.

    Essayez d’ assert.sh

     source "./assert.sh" local expected actual expected="Hello" actual="World!" assert_eq "$expected" "$actual" "not equivalent!" # => x Hello == World :: not equivalent! 

    J’espère que cela aide!

    Nikita Sobolev a écrit un excellent article de blog comparant quelques différents frameworks de test bash: Test des applications Bash

    Pour les impatients: la conclusion de Nikita était d’utiliser les chauves-souris, mais il semble que Nikita ait manqué le projet Bats-core qui me semble être celui qui sera utilisé dans la mesure où le projet Bats original n’a pas été activement maintenu depuis 2013.

    J’aime bien shell2junit , un utilitaire permettant de générer une sortie de type JUnit à partir de tests de script Bash. Ceci est utile car le rapport généré peut ensuite être lu par des systèmes d’continuous integration, tels que les plug-ins JUnit pour Jenkins et Bamboo.

    Bien que shell2junit ne fournisse pas la structure de script complète de Bash comme shunit2 , il vous permet de générer des rapports de qualité sur les résultats des tests.

    Vous pourriez vouloir jeter un oeil à bash_unit:

    https://github.com/pgrange/bash_unit

    J’ai eu du mal à justifier l’utilisation de bash pour des scripts plus volumineux lorsque Python présente des avantages considérables:

    • Try / Except permet d’écrire des scripts plus robustes avec la possibilité d’annuler les modifications en cas d’erreur.
    • Vous n’avez pas besoin d’utiliser une syntaxe obscure telle que ‘ if [ x"$foo" = x"$bar"]; then ... if [ x"$foo" = x"$bar"]; then ... ‘qui est sujet aux erreurs.
    • Analyse facile des options et des arguments en utilisant le module getopt (et il y a un module encore plus simple pour parsingr les arguments, mais le nom m’échappe).
    • Python vous permet de travailler avec des listes / dicts et des objects plutôt que des chaînes et des tableaux de base.
    • Accès à des outils de langage appropriés tels que regex, database (assurez-vous de pouvoir tout mysql dans la commande mysql dans bash, mais ce n’est pas la meilleure façon d’écrire du code).
    • Pas besoin de s’inquiéter d’utiliser la forme correcte de $* ou "$*" ou "$@" ou $1 ou "$1" , les espaces dans les noms de fichiers ne sont pas un problème, etc., etc., etc.

    Maintenant, j’utilise uniquement bash pour les scripts les plus simples.