2012-04-12 21 views
6

Jestem bardzo nowy w pisaniu skryptów i mam problem z ustaleniem, jak zacząć skrypt basha, który automatycznie przetestuje wyjście programu na oczekiwane wyjście.Skrypt Bash do automatycznego testowania wyjścia programu - C

Chcę napisać skrypt bash, który uruchomi określony plik wykonywalny na zestawie wejść testowych, np. In1 in2 itd., Odpowiadających oczekiwanym wyjściom, out1, out2 itd. I sprawdzi, czy pasują do siebie. Plik do przetestowania odczytuje dane wejściowe ze standardowego wejścia i wypisze dane wyjściowe na standardowe wyjście. Zatem wykonanie programu testowego na pliku wejściowym będzie wymagało przekierowania we/wy.

Skrypt zostanie wywołany z jednym argumentem, który będzie nazwą testowanego pliku wykonywalnego.

Mam problem z tym, że po prostu to robię, więc jakakolwiek pomoc (linki do wszelkich zasobów, które dodatkowo wyjaśnią, w jaki sposób mogę to zrobić) byłyby bardzo mile widziane. Najwyraźniej próbowałam się przeszukać, ale nie odniosłam w tym sukcesu.

Dzięki!

+1

Można użyć poleceń 'diff' lub' cmp' do porównania wyjść. –

+0

Programy 'diff',' cmp' i 'comm' (szczególnie pierwsze dwa) służą do porównywania dwóch plików. Można więc przechwycić oczekiwane dane wyjściowe w jednym pliku, rzeczywisty wynik w innym, a następnie porównać pliki. To najprostszy sposób na zrobienie tego; niekoniecznie jest najlepszy. –

+0

Myślę, że twój opis jest trochę nie tak. Sposób, w jaki ją czytam, chcesz, aby dane wejściowe pasowały do ​​wyjść. Ale myślę, że masz na myśli, że masz wejścia testowe, rzeczywiste wyniki i oczekiwane wyniki. I chcesz rozróżnić dwa ostatnie. – Mikel

Odpowiedz

0

Funkcje. Herestrings. Przekierowanie. Substytucja procesu. diff -q. test.

2

Expect może być idealnym rozwiązaniem dla tego rodzaju problemu:

Expect jest narzędziem przede wszystkim do automatyzacji aplikacji interaktywnych, takich jak telnet , ftp, passwd, fsck, rlogin, cynk, itp Expect naprawdę sprawia, że ​​te sprawy są banalne. Expect jest również przydatny do testowania tych samych aplikacji .

0

Oczekiwane wyniki to drugi rodzaj danych wejściowych.

Na przykład, jeśli chcesz przetestować funkcję kwadratową, otrzymasz dane wejściowe takie jak (0, 1, 2, -1, -2) i oczekiwane wyjście jako (0, 1, 4, 1, 4).

Następnie można porównać każdy wynik wejścia z oczekiwanym wynikiem i na przykład zgłosić błędy.

Można pracować z tablicami:

in=(0 1 2 -1 -2) 
out=(0 1 4 2 4) 

for i in $(seq 0 $((${#in[@]}-1))) 
do 
    ((${in[i]} * ${in[i]} - ${out[i]})) && echo -n bad" " || echo -n fine" " 
    echo $i ": " ${in[i]}"² ?= " ${out[i]} 
done 

fine 0 : 0² ?= 0 
fine 1 : 1² ?= 1 
fine 2 : 2² ?= 4 
bad 3 : -1² ?= 2 
fine 4 : -2² ?= 4 

Oczywiście można przeczytać obie tablice z pliku.

Testowanie za pomocą ((...)) może wywoływać wyrazy arytmetyczne, łańcuchy i pliki. Wypróbuj

help test 

, aby uzyskać przegląd.

Reading strings WordWise z pliku:

for n in $(< f1); do echo $n "-" ; done 

Czytaj na tablicy:

arr=($(< file1)) 

Czytaj plik linewise:

for i in $(seq 1 $(cat file1 | wc -l)) 
do 
    line=$(sed -n ${i}p file1) 
    echo $line"#" 
done 

Testowanie przed programem wyjście brzmi porównaniu smyczkowy i przechwytywanie wyjścia programu n=$(cmd param1 param2):

asux:~/prompt > echo -e "foo\nbar\nbaz" 
foo 
bar 
baz 
asux:~/prompt > echo -e "foo\nbar\nbaz" > file 
asux:~/prompt > for i in $(seq 1 3); do line=$(sed -n ${i}p file); test "$line" = "bar" && echo match || echo fail ; done 
fail 
match 
fail 

Dalsze usesful: Wyrażenie regularne pasujące na smyczki z = ~ w [[...]] nawiasach:

for i in $(seq 1 3) 
do 
    line=$(sed -n ${i}p file) 
    echo -n $line 
    if [[ "$line" =~ ba. ]]; then 
    echo " "match 
    else echo " "fail 
    fi 
done 
foo fail 
bar match 
baz match 
8

Jeśli to, co chcesz; to może zacząć:

Mieszanka bash + narzędzia zewnętrzne, takie jak diff.

#!/bin/bash 

# If number of arguments less then 1; print usage and exit 
if [ $# -lt 1 ]; then 
    printf "Usage: %s <application>\n" "$0" >&2 
    exit 1 
fi 

bin="$1"   # The application (from command arg) 
diff="diff -iad" # Diff command, or what ever 

# An array, do not have to declare it, but is supposedly faster 
declare -a file_base=("file1" "file2" "file3") 

# Loop the array 
for file in "${file_base[@]}"; do 
    # Padd file_base with suffixes 
    file_in="$file.in"    # The in file 
    file_out_val="$file.out"  # The out file to check against 
    file_out_tst="$file.out.tst" # The outfile from test application 

    # Validate infile exists (do the same for out validate file) 
    if [ ! -f "$file_in" ]; then 
     printf "In file %s is missing\n" "$file_in" 
     continue; 
    fi 
    if [ ! -f "$file_out_val" ]; then 
     printf "Validation file %s is missing\n" "$file_out_val" 
     continue; 
    fi 

    printf "Testing against %s\n" "$file_in" 

    # Run application, redirect in file to app, and output to out file 
    "./$bin" < "$file_in" > "$file_out_tst" 

    # Execute diff 
    $diff "$file_out_tst" "$file_out_val" 


    # Check exit code from previous command (ie diff) 
    # We need to add this to a variable else we can't print it 
    # as it will be changed by the if [ 
    # Iff not 0 then the files differ (at least with diff) 
    e_code=$? 
    if [ $e_code != 0 ]; then 
      printf "TEST FAIL : %d\n" "$e_code" 
    else 
      printf "TEST OK!\n" 
    fi 

    # Pause by prompt 
    read -p "Enter a to abort, anything else to continue: " input_data 
    # Iff input is "a" then abort 
    [ "$input_data" == "a" ] && break 

done 

# Clean exit with status 0 
exit 0 

Edit.

Dodano kontrolę kodu wyjścia; I krótki spacer koryta:

Ta wola w krótkim zrobić:

  1. Sprawdź, czy podano argumentu (bin/aplikacji)
  2. Użyj tablicę „nazw podstawowych”, pętli tego i generować prawdziwych nazw .
    • Ie: Mając tablicę ("file1" "file2") masz
      • W pliku: file1.in
      • Out pliku do sprawdzania przed: file1.out
      • Out pliku: file1.out.tst
      • W pliku: file2.in
      • . ..
  3. Wykonanie aplikacji i przekierowania w pliku stdin do stosowania przez < i przekierować stdout z aplikacji na zewnątrz testu plików przez >.
  4. Użyj narzędzia takiego jak np. diff, aby sprawdzić, czy są takie same.
  5. Sprawdź kod wyjścia/powrotu z narzędzia i wydrukuj wiadomość (FAIL/OK)
  6. Pytaj o kontynuację.

Którego z kursów można modyfikować, usuwać itp.


Niektóre linki:

+0

Wow, dziękuję bardzo! – Shabu

0

Pierwszy przyjrzeć rozdziale Zaawansowane Bash-Scripting Guide na I/O redirection.

Następnie muszę zapytać Dlaczego w ogóle używać skryptu Bash? Zrób to bezpośrednio z pliku makefile.

Na przykład mam generic makefile zawierający coś takiego:

# type 'make test' to run a test. 
# for example this runs your program with jackjill.txt as input 
# and redirects the stdout to the file jackjill.out 
test: $(program_NAME) 
     ./$(program_NAME) <jackjill.txt> jackjill.out 
     ./diff -q jackjill.out jackjill.expected 

Można dodać dowolną liczbę testów, jak chcesz tak. Po prostu różnicujesz plik wyjściowy za każdym razem, gdy plik zawiera oczekiwane dane wyjściowe.

Oczywiście ma to znaczenie tylko, jeśli faktycznie używasz pliku Makefile do budowania programu. :-)

Powiązane problemy