Sono nello unit testing di alcuni script di shell legacy.Test dell'unità Script di shell: Come creare un programma di utilità complesso
Negli script del mondo reale sono spesso utilizzati per chiamare i programmi di utilità come find
, tar
, cpio
, grep
, sed
, rsync
, date
e così via con alcune righe di comando piuttosto complesse che contengono un sacco di opzioni. A volte vengono costruite e utilizzate espressioni regolari o pattern jolly.
Un esempio : Uno script di shell che di solito è richiamato da cron ad intervalli regolari ha il compito di rispecchiare alcuni alberi di directory enormi da un computer all'altro utilizzando l'utilità rsync. diversi tipi di file e directory dovrebbero essere esclusi dal processo mirroring:
#!/usr/bin/env bash
...
function mirror() {
...
COMMAND="rsync -aH$VERBOSE$DRY $PROGRESS $DELETE $OTHER_OPTIONS \
$EXCLUDE_OPTIONS $SOURCE_HOST:$DIRECTORY $TARGET"
...
if eval $COMMAND
then ...
else ...
fi
...
}
...
Come Michael Feathers ha scritto nel suo famoso libro Working Effectively with Legacy Code, una buona prova di unità corre molto veloce e non tocca la rete, il file- sistema o apre qualsiasi database.
Seguendo il consiglio di Michael Feathers la tecnica da utilizzare qui è: dependency injection. L'oggetto da sostituire qui è il programma di utilità rsync
.
La mia prima idea: nel mio guscio framework di testing sceneggiatura (io uso bats) manipolo $PATH
in un modo che un mockuprsync
è trovato al posto del il vero rsync
utility. Questo oggetto mockup potrebbe verificare i parametri e le opzioni della riga di comando forniti. Simile ad altre utilità utilizzate in questa parte di script under test.
Le mie esperienze passate con problemi reali in quest'area di scripting erano spesso errori causati da caratteri speciali nei nomi di file o directory, problemi di quoting o codifiche, chiavi ssh mancanti, autorizzazioni errate e così via. Questo tipo di bug sarebbe sfuggito a questa tecnica di test unitario. (Lo so: per alcuni di questi problemi il test dell'unità non è semplicemente la cura).
Un altro svantaggio è che scrivere un mockup per un programma di utilità complesso come rsync
o find
è soggetto ad errori e un compito di ingegneria noiosa propria.
Credo che la situazione descritta sopra sia abbastanza generale che altre persone potrebbero aver riscontrato problemi simili. Chi ha delle idee intelligenti e vorrebbe condividerle qui con me?
Dopo unit testing, è necessario test di sistema. Forse costruisci una semplice rete di test con uno ciascuno dei file problematici, directory, chiavi mancanti, ecc. – tripleee
Usa 'tee' in linea con uno scenario reale per catturare risposte di comando chiamate, quindi usa quei file per riprodurli nello scenario imbrigliato da test , forse con uno script che registra gli argomenti ricevuti e invia ciecamente la risposta predefinita. –
@Keith Tyler: Questa è un'idea molto carina: ovviamente questa tecnica richiede una sorta di test di sistema scritto in anticipo (ma quando si inizia a giocherellare su uno script legacy, scrivere almeno alcuni di questi test prima di iniziare a ridefinire lo script è comunque un buon idea). Complimenti per questo suggerimento. – pefu