Bash脚本自动测试程序输出 - C.

时间:2012-04-12 06:20:04

标签: bash automated-tests

我是编写脚本的新手,我无法弄清楚如何开始使用bash脚本,该脚本会根据预期的输出自动测试程序的输出。

我想编写一个bash脚本,它将在一组测试输入上运行指定的可执行文件,例如in1 in2等,对应相应的预期输出,out1,out2等,并检查它们是否匹配。要测试的文件从stdin读取其输入并将其输出写入stdout。因此,在输入文件上执行测试程序将涉及I / O重定向。

将使用单个参数调用脚本,该参数将是要测试的可执行文件的名称。

我在这方面遇到了麻烦,所以任何帮助(链接到任何资源,进一步解释我如何能够做到这一点)将不胜感激。我显然已经尝试过自己寻找但是并没有那么成功。

谢谢!

5 个答案:

答案 0 :(得分: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 / application)
  2. 使用“基本名称”数组,循环并生成真正的文件名。
    • 即:你有阵列("file1" "file2")
      • 在档案中:file1.in
      • 要验证的文件:file1.out
      • 输出文件:file1.out.tst
      • 在档案中:file2.in
      • ...
  3. 执行应用程序并将文件重定向到stdin以便<申请,并通过stdout>从应用程序重定向到文件测试。
  4. 使用像diff这样的工具来测试它们是否相同。
  5. 检查工具中的退出/返回代码并打印消息(FAIL / OK)
  6. 提示继续。
  7. 任何和所有当然可以修改,删除等。


    一些链接:

答案 1 :(得分:2)

Expect可能非常适合这类问题:

  

Expect是一款主要用于自动化交互式应用程序的工具   比如telnet,f​​tp,passwd,fsck,rlogin,tip等。期待真的   使这些东西变得微不足道。期望对于测试这些也是有用的   应用

答案 2 :(得分:0)

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

答案 3 :(得分:0)

预期产出是第二种输入。

例如,如果要测试平方函数,则输入为(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

进一步有用:在[[...]]括号中使用=〜的字符串上的正则表达式匹配:

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

答案 4 :(得分:0)

首先看一下I/O redirection上的高级Bash-Scripting Guide章节。

然后我不得不问为什么要使用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构建程序时,这才有意义。 : - )