2012-04-12 52 views
6

我對編寫腳本非常陌生,我無法弄清楚如何開始使用bash腳本,該腳本會根據預期輸出自動測試程序的輸出。Bash腳本自動測試程序輸出 - C

我想編寫一個bash腳本,它將在一組測試輸入(比如in1 in2等)上運行指定的可執行文件,並針對相應的期望輸出out1,out2等,並檢查它們是否匹配。要測試的文件從stdin讀取其輸入並將其輸出寫入stdout。因此,在輸入文件上執行測試程序將涉及I/O重定向。

該腳本將被調用一個參數,這將是要測試的可執行文件的名稱。

我很難開始這個,所以任何幫助(鏈接到任何資源,進一步解釋我如何能做到這一點)將不勝感激。我顯然已經嘗試過尋找自己,但在這方面還沒有取得成功。

謝謝!

+1

您可以使用'diff'或'cmp'命令來比較輸出。 – 2012-04-12 06:21:41

+0

'diff','cmp'和'comm'程序(特別是前兩個)用於比較兩個文件。因此,您可以在一個文件中捕獲預期的輸出,在另一個文件中捕獲實際輸出,然後比較文件。這是最簡單的方法;它不一定是最好的。 – 2012-04-12 06:22:24

+0

我認爲你的描述有點不對。我閱讀它的方式,你希望輸入與輸出匹配。但我認爲你的意思是你有測試輸入,實際輸出和預期輸出。而你想要區分最後兩個。 – Mikel 2012-04-12 07:09:07

回答

0

功能。 Herestrings。重定向。流程替換。 diff -qtest

2

Expect可能是這類問題一個完美的結合:

期待是一種工具,主要用於自動化交互式應用 如telnet,f​​tp,passwd文件時,fsck,遠程登錄,尖端等期待真正 使這個東西微不足道。期望對測試這些相同的應用程序也很有用。

0

預期輸出是第二種輸入。例如,如果要測試平方函數,則需要輸入(0,1,2,-1,-2)和期望輸出(0,1,4,1,4)。例如,如果要測試平方函數,則需要輸入(0,1,2,-1,-2)和期望輸出(0,1,4,1,4)。

然後,您會比較輸入的每個結果與預期輸出並報告錯誤。

你可以使用數組:

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 

當然,你可以從文件中讀取兩個陣列。

使用((...))進行測試可以調用算術表達式,字符串和文件。嘗試

help test 

有關概述。

讀字符串從文件中字方式:

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

讀入一個數組:

arr=($(< file1)) 

讀取文件面向行:

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

測試針對程序輸出聽起來像字符串比較和捕獲程序輸出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 

而且usesful:正則表達式[[...]]括號用=〜弦上的匹配:

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

如果我得到你想要的東西;這可能會讓你開始:

混合使用bash +外部工具,如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 

編輯。

增加了退出碼檢查;而幾步之遙槽:

這將在短期做:

  1. 檢查,如果給定參數(BIN /應用)
  2. 使用的「基本名稱」,循環這個數組,併產生實際文件名。
    • 即:陣列具有("file1" "file2")
      • 在文件:file1.in
      • 輸出文件來驗證:file1.out
      • 輸出文件:file1.out.tst
      • 在文件:file2.in
      • 。 ..
  3. 執行應用程序並通過<在文件重定向到stdin爲應用程序,並通過>重定向從應用到了所有的文件測試stdout
  4. 使用像diff這樣的工具來測試它們是否相同。
  5. 檢查工具和打印信息的退出/退回代碼(FAIL/OK)
  6. 提示繼續。

任何和所有的偏航過程都可以修改,刪除等。


某些鏈接:

+0

非常感謝你! – Shabu 2012-04-12 10:14:06

0

首先來看看在I/O redirection高級Bash腳本編程指南一章。

然後我必須問爲什麼使用bash腳本?直接從你的makefile中執行。

比如我有一個包含一些generic makefile這樣的:

# 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 

,只要你想這樣你可以添加儘可能多的測試。您只需每次對包含預期輸出的文件比較輸出文件即可。

當然這隻有在你使用makefile來構建你的程序時纔有意義。 :-)