Domanda

Abbiamo un sistema che ha alcuni script bash in esecuzione oltre a codice Java. Dal momento che stiamo cercando di prova tutto ciò che potrebbe rompere, e quegli script bash potrebbe rompersi, vogliamo metterli alla prova.

Il problema è che è difficile da testare script bash.

C'è un modo o di una pratica migliore per testare script bash? O dovremmo smettere di usare script bash e cercare soluzioni alternative che siano verificabili?

È stato utile?

Soluzione 2

ho ricevuto la seguente risposta da un gruppo di discussione:

  

è possibile importare (includere,   qualunque sia) una procedura (funzione,   tutto ciò prende il nome) da un esterno   file. Questa è la chiave per la scrittura di un   script di test: si rompe il vostro   script in procedure indipendenti   che possono poi essere importati in entrambi   lo script in esecuzione e la vostra prova   sceneggiatura, e poi ci sono la vostra corsa   script di essere il più semplice possibile.

Questo metodo è come l'iniezione di dipendenza per gli script, e sembra ragionevole. Evitare script bash e usare un linguaggio più verificabili e meno oscura è preferibile.

Altri suggerimenti

Non è in realtà un shunit2 , un framework di unit test xUnit based per gli script di shell a base di Bourne. Non ho usato io stesso, ma potrebbe essere la pena di verificare.

Domande simili sono state poste prima:

TAP test Bash -compatibile: Bash Automated Testing System

  

TAP, l'Anything Protocol Test, è una semplice interfaccia basata su testo tra i moduli di test in un test harness. TAP ha iniziato la vita come parte del test harness per Perl, ma ora ha implementazioni in C, C ++, Python, PHP, Perl, Java, JavaScript, e altri.

Epoxy è un framework di test Bash ho progettato principalmente per testare altri software, ma lo uso per testare moduli bash così, tra stessa e Carton .

I principali vantaggi sono relativamente basso overhead di codifica, senza limiti di nidificazione affermazione e la selezione flessibile di affermazioni da verificare.

Ho fatto un presentazione confrontandolo con BeakerLib -. un quadro utilizzato da alcuni a Red Hat

Nikita Sobolev ha scritto un ottimo post sul blog a confronto alcuni quadri di prova diversa bash: applicazioni di test Bash

Per gli impazienti: la conclusione di Nikita era quello di utilizzare Bats ma sembra che Nikita mancato il progetto Bats-core, che mi sembra essere quello da usare in futuro come il progetto pipistrelli originali non è stato attivamente sostenuto dal 2013.

Perché dici che è "duro" per testare script bash?

Cosa c'è di sbagliato con involucri di test come:

 #!/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
 }

mi piace molto shell2junit , un programma di utilità per generare l'output JUnit-come dai test script bash. Questo è utile perché il report generato può poi essere letti da sistemi di integrazione continui, come le JUnit plug-in per Jenkins e di bambù.

Mentre shell2junit non fornisce il quadro completo Bash scripting come shunit2 , se non è permessa avete bella segnalazione dei risultati del test.

bashtest . It `s modo semplice per testare i vostri script. Ad esempio, si dispone di do-some-work.sh che cambiano alcuni file di configurazione. Ad esempio, aggiungere nuova PASSWORD = 'XXXXX' riga in config file di /etc/my.cfg.

Si scrive bash linea comandi per riga e poi controllare l'uscita.

Installare:

pip3 install bashtest

Crea test è un comandi bash solo scrivendo.

test-do-some-work.bashtest file:

# 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

Esecuzione dei test:

bashtest *.bashtest

Si possono trovare alcuni esempi qui e qui

Forse questo può essere utilizzato, o contribuito a

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

Destinato a dare risultati in protocollo TAP che immagino è un bene per CI, e buono per coloro che vogliono ambienti shell. Immagino che alcune cose eseguiti nell'ambiente di shell giù di lì, alcuni potrebbero sostenere dovrebbe essere testato nel loro ambiente di shell.

dare una prova di assert.sh

source "./assert.sh"

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

Speranza che aiuta!

Non posso credere che nessuno ha parlato di OSHT ! E 'compatibile con sia TAP e JUnit, suo guscio puro (cioè, senza altre lingue coinvolti), funziona standalone troppo, ed è semplice e diretto.

Test si presenta così (frammenti tratti dalla pagina del progetto):

#!/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

Una corsa semplice:

$ 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

L'ultimo test mostra come "non ok", ma il codice di uscita è 0 perché è un TODO. Si può impostare verbose così:

$ 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

Rinomina in modo da utilizzare un'estensione .t e metterlo in una sottodirectory t, ed è possibile utilizzare prove(1) (parte di Perl) per eseguirlo:

$ 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 o passare -j per produrre un output JUnit. JUnit può anche essere combinato con prove(1).

Ho usato questa biblioteca sia funzioni di test da sourcing i propri file e quindi eseguire affermazioni con IS / OK e loro negativi, e gli script utilizzando RUN / NRUN. Per me, questo quadro fornisce la maggior parte del guadagno per il meno spese generali.

shellspec perché volevo un facile da usare e utile strumento.

E 'stato scritto da script di pura shell POSIX. Si è provato con molte conchiglie più di shunit2. Ha caratteristiche potenti di pipistrelli / pipistrelli-core.

Ad esempio, il supporto blocco nidificato, facile deridere / stub, facile saltare / attesa, test con parametri, numero di riga affermazione, eseguite dal numero di riga, esecuzione parallela, esecuzione casuale, TAP / JUnit formattatore, copertura e integrazione CI, profiler ed ecc.

Visualizza la demo sulla pagina del progetto.

Ho provato un sacco di soluzioni presentate qui, ma ha trovato la maggior parte di loro di ingombranti e difficili da usare, così ho costruito il mio quadro piccolo test: https://github.com/meonlol/t-bash

E 'solo un file nel repository che si può semplicemente eseguire direttamente, con un set base di stile JUnit afferma.

L'ho usato in modo professionale in numerosi progetti interni e sono stati in grado di rendere i nostri script bash super-stabile e resistente di regressione.

Si potrebbe voler dare un'occhiata a bash_unit:

https://github.com/pgrange/bash_unit

Date un'occhiata a Outthentic , è semplice, estendibile da molte lingue (Perl, Python, Ruby, Bash sulla scelta) e cross-platform (Linux, Windows) framework per testare tutte le applicazioni a riga di comando.

Ho trovato difficile giustificare l'uso bash per gli script più grandi quando Python ha tali vantaggi enormi:

  • Prova / Tranne permette la scrittura di script più robusti con la possibilità di annullare le modifiche in caso di errore.
  • Non c'è bisogno di usare la sintassi oscura come 'if [ x"$foo" = x"$bar"]; then ...', che è soggetto a errori.
  • Facile analisi delle opzioni e gli argomenti utilizzando il modulo getopt (e c'è un modulo ancora più semplice per l'analisi di argomenti, ma mi sfugge il nome).
  • Python consente di lavorare con liste / dicts e oggetti invece di stringhe e array di base.
  • L'accesso a strumenti linguistici adeguati, quali espressioni regolari, basi di dati (che si poteva tubo tutto nel comando mysql in bash, ma non è il modo più bello di scrivere codice).
  • Non c'è bisogno di preoccuparsi di usare la forma corretta di $* o "$*" o "$@" o $1 o "$1", spazi nei nomi dei file non è un problema, ecc, ecc, ecc.

Ora io uso solo bash per il più semplice degli script.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top