Frage

Wir haben ein System, das einige Bash-Skripte laufen neben Java-Code hat. Da wir das könnte möglicherweise Break-Test Alles versuchen, und die Bash-Skripte brechen können, wollen wir sie testen.

Das Problem ist, es zu testen Bash-Skripte hart ist.

Gibt es eine Möglichkeit oder eine bewährte Methode, um Test Bash-Skripte? Oder sollte beenden wir Bash-Skripte und suchen nach alternativen Lösungen verwenden, die überprüfbar sind?

War es hilfreich?

Lösung 2

Ich habe folgende Antwort aus einer Diskussionsgruppe:

  

ist es möglich, zu importieren (enthalten,   was auch immer) ein Verfahren (Funktion,   was auch immer es genannt) von einem externen   Datei. Das ist der Schlüssel zum Schreiben eines   Testskript: Sie brechen Ihre   Skript in unabhängige Verfahren   das kann dann in beide importiert werden   Ihre laufenden Skript und Ihre Tests   Skript, und dann haben Sie Ihren Lauf   Skript so einfach wie möglich.

Dieses Verfahren ist wie Dependency Injection für Skripte und klingt vernünftig. Bash-Skripte zu vermeiden und mit mehr prüfbar und weniger obskuren Sprache vorzuziehen.

Andere Tipps

Es gibt tatsächlich einen shunit2 , eine xUnit basierte Einheit Test-Framework für Bourne basierte Shell-Skripten. Ich habe es selbst nicht benutzt, aber es könnte ein Besuch wert sein.

ähnliche Fragen wurden gebeten, vor:

TAP -konforme Bash Test: Bash Automatisiertes Testing System

  

TAP, der Test-Anything Protocol, ist eine einfache textbasierte Schnittstelle zwischen den Modulen in einer Testumgebung zu testen. TAP begann das Leben als Teil der Testumgebung für Perl aber jetzt hat Implementierungen in C, C ++, Python, PHP, Perl, Java, JavaScript und andere.

Epoxy ist ein Bash-Test-Framework ich hauptsächlich zum Testen andere Software entwickelt, aber ich benutze es, um Test bash-Module als auch, wie selbst und Carton .

Die wichtigsten Vorteile relativ niedriger Codierungsaufwand, unbegrenzte Behauptung Verschachtelung und flexible Auswahl von Behauptungen zu überprüfen.

Ich habe eine Präsentation es auf BeakerLib -. ein Rahmen von einigen bei Red Hat verwendet

schrieb Nikita Sobolev eine ausgezeichnete Blog-Post, ein paar verschiedene Bash Test-Frameworks zu vergleichen: Testing Bash Anwendungen

Für Ungeduldige: Nikitas Schlussfolgerung war, zu benutzen Bats aber es scheint, dass Nikita verpasst das Bats-Core Projekt, das mir zu sein scheint das eine wie das Original Fledermäuse Projekt für die Zukunft zu nutzen hat sich seit 2013 aktiv beibehalten.

Warum sagen Sie, dass es „hart“ zu Test Bash-Skripte?

Was ist mit Test-Wrapper falsch ist wie:

 #!/bin/bash
 set -e
 errors=0
 results=$($script_under_test $args<<ENDTSTDATA
 # inputs
 # go
 # here
 #
 ENDTSTDATA
 )
 [ "$?" -ne 0 ] || {
     echo "Test returned error code $?" 2>&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
 }

Ich mag shell2junit , ein Dienstprogramm JUnit-ähnliche Ausgabe von Bash-Skript Tests zu generieren. Dies ist nützlich, weil der Bericht erzeugt wird, kann dann durch kontinuierliche Integration Systeme gelesen werden, wie die JUnit-Plug-In für Jenkins und Bambus.

Während shell2junit nicht die umfassende Bash Scripting nicht bieten Framework wie shunit2 , es erlaubt Sie haben schöne Berichterstattung über die Testergebnisse.

Versuchen Sie bashtest . It`s einfache Möglichkeit, Ihre Skripte zu testen. Zum Beispiel haben Sie do-some-work.sh die einige Konfigurationsdateien ändern. Fügen Sie zum Beispiel neue Zeile PASSWORD = 'XXXXX' zu Konfigurationsdatei /etc/my.cfg.

Sie schreiben bash Befehle Zeile für Zeile und dann ausgegeben überprüfen.

Installieren:

pip3 install bashtest

Tests erstellen ist ein einfach zu schreiben bash Befehle.

Datei 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

Run Tests:

bashtest *.bashtest

Sie können finden einige Beispiele hier und hier

Vielleicht kann dies verwendet werden, oder mitverursacht

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

Beabsichtigte zu schreiben Ergebnisse in TAP-Protokoll, das ich mir vorstellen, ist gut für CI und gut für diejenigen, die Shell-Umgebungen wollen. Ich stelle mir vor ein paar Dinge in Shell-Umgebungen laufen, so argumentieren einige könnten, sollten in ihrer Shell-Umgebung getestet werden.

Geben Sie einen Versuch assert.sh

source "./assert.sh"

local expected actual
expected="Hello"
actual="World!"
assert_eq "$expected" "$actual" "not equivalent!"
# => x Hello == World :: not equivalent!

Hope, es hilft!

Ich kann niemand glauben, sprach über OSHT ! Es ist kompatibel mit beide TAP und JUnit, es ist reine Schale (das heißt, keine andere Sprachen beteiligt ist), es funktioniert eigenständige auch, und es ist einfach und direkt.

Test sieht wie folgt aus (Auszüge aus der Projektseite entnommen):

#!/bin/bash
. osht.sh

# Optionally, indicate number of tests to safeguard against abnormal exits
PLAN 13

# Comparing stuff
IS $(whoami) != root
var="foobar"
IS "$var" =~ foo
ISNT "$var" == foo

# test(1)-based tests
OK -f /etc/passwd
NOK -w /etc/passwd

# Running stuff
# Check exit code
RUNS true
NRUNS false

# Check stdio/stdout/stderr
RUNS echo -e 'foo\nbar\nbaz'
GREP bar
OGREP bar
NEGREP . # verify empty

# diff output
DIFF <<EOF
foo
bar
baz
EOF

# TODO and SKIP
TODO RUNS false
SKIP test $(uname -s) == Darwin

Ein einfacher Lauf:

$ bash test.sh
1..13
ok 1 - IS $(whoami) != root
ok 2 - IS "$var" =~ foo
ok 3 - ISNT "$var" == foo
ok 4 - OK -f /etc/passwd
ok 5 - NOK -w /etc/passwd
ok 6 - RUNS true
ok 7 - NRUNS false
ok 8 - RUNS echo -e 'foo\nbar\nbaz'
ok 9 - GREP bar
ok 10 - OGREP bar
ok 11 - NEGREP . # verify empty
ok 12 - DIFF <<EOF
not ok 13 - TODO RUNS false # TODO Test Know to fail

Der letzte Test zeigt als „nicht ok“, aber der Exit-Code ist 0, weil es ein TODO ist. Man kann einstellen ausführliche auch:

$ OSHT_VERBOSE=1 bash test.sh # Or -v
1..13
# dcsobral \!= root
ok 1 - IS $(whoami) != root
# foobar =\~ foo
ok 2 - IS "$var" =~ foo
# \! foobar == foo
ok 3 - ISNT "$var" == foo
# test -f /etc/passwd
ok 4 - OK -f /etc/passwd
# test \! -w /etc/passwd
ok 5 - NOK -w /etc/passwd
# RUNNING: true
# STATUS: 0
# STDIO <<EOM
# EOM
ok 6 - RUNS true
# RUNNING: false
# STATUS: 1
# STDIO <<EOM
# EOM
ok 7 - NRUNS false
# RUNNING: echo -e foo\\nbar\\nbaz
# STATUS: 0
# STDIO <<EOM
# foo
# bar
# baz
# EOM
ok 8 - RUNS echo -e 'foo\nbar\nbaz'
# grep -q bar
ok 9 - GREP bar
# grep -q bar
ok 10 - OGREP bar
# \! grep -q .
ok 11 - NEGREP . # verify empty
ok 12 - DIFF <<EOF
# RUNNING: false
# STATUS: 1
# STDIO <<EOM
# EOM
not ok 13 - TODO RUNS false # TODO Test Know to fail

Umbenennen eine .t Erweiterung zu benutzen und es in einem Unterverzeichnis t setzen, und Sie können prove(1) (Teil von Perl) verwenden, um sie auszuführen:

$ prove
t/test.t .. ok
All tests successful.
Files=1, Tests=13,  0 wallclock secs ( 0.03 usr  0.01 sys +  0.11 cusr  0.16 csys =  0.31 CPU)
Result: PASS

Set OSHT_JUNIT oder Pass -j zu produzieren JUnit-Ausgang. JUnit kann auch mit prove(1) kombiniert werden.

Ich habe diese Bibliothek beide Testfunktionen, die von ihren Dateien Sourcing und dann Behauptungen mit IS / OK und ihre Negative läuft, und Skripte durch RUN / NRUN verwenden. Für mich stellt dieser Rahmen den meisten Gewinn für den am wenigsten Aufwand.

Ich habe shellspec , weil ich ein einfach zu bedienendes und nützliches Werkzeug wollte.

Es durch reinen POSIX-Shell-Skript geschrieben. Es hat mit vielen Muscheln mehr als shunit2 getestet. Es verfügt über leistungsfähige Funktionen als Fledermaus / bats-Kern.

Beispiel Unterstützung verschachtelter Block, leicht zu mock / stub, leicht zu überspringen / anhängiger, parametrisiert Tests Assertion Zeilennummer, führt durch die Zeilennummer, die parallele Ausführung, zufällige Ausführung, TAP / JUnit Formatierer, Abdeckung und CI-Integration, Profiler und etc.

Sehen Sie die Demo auf der Projektseite.

Ich habe viele Lösungen versucht hier präsentierten, fand aber die meisten von ihnen Gebrauch sperrig und schwer, so dass ich meine eigene kleine Test-Framework aufgebaut: https://github.com/meonlol/t-bash

Es ist nur eine Datei in der Repo, dass man einfach direkt behauptet mit einem Basissatz von JUnit-Stil ausgeführt werden kann.

habe ich es professionell in verschiedenen internen Projekten eingesetzt und konnte unseren Bash-Skripte super stabil und Regression resistent machen.

Sie können einen Blick auf bash_unit nehmen wollen:

https://github.com/pgrange/bash_unit

Hier finden Sie aktuelle Outthentic , es ist einfach, erweiterbar durch viele Sprachen (Perl, Python, Ruby, Bash auf Wahl) und Cross-Plattform (Linux, Windows) Rahmen keine Kommandozeilen-Applikationen zu testen.

Ich habe es schwer gefunden bash für größere Skripte zu rechtfertigen, wenn Python hat so große Vorteile:

  • try / except ermöglicht robustere Skripte mit der Fähigkeit zu schreiben rückgängig zu machen im Falle eines Fehlers ändert.
  • Sie müssen nicht darüber hinwegtäuschen Syntax wie ‚if [ x"$foo" = x"$bar"]; then ...‘, die fehleranfällig ist.
  • Einfache Analyse von Optionen und Argumente mit dem getopt Modul (und es gibt eine noch einfachere Modul Argumente für das Parsen, aber der Name entgeht mir).
  • Python können Sie die Arbeit mit Listen / dicts und Objekte anstelle von grundlegenden Strings und Arrays.
  • Zugriff auf die richtige Sprache Tools wie regex, Datenbanken (sicher, Sie könnten Rohr alles in den mysql Befehl in bash, aber es ist nicht die schönste Art und Weise zu schreiben Code).
  • Kein Grund zur Sorge über die richtige Form von $* oder "$*" oder "$@" oder $1 oder "$1" verwenden, Leerzeichen in Dateinamen ist kein Problem, etc, etc, etc.

Jetzt habe ich nur bash für die einfachsten Skripte verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top