使用shUnit2在bash脚本中测试“退出流程命令”

时间:2015-08-13 17:12:42

标签: bash shell unit-testing shunit2

根据这个问题的一个技巧is-there-a-way-to-write-a-bash-function-which-aborts-the-whole-execution...

我的示例代码(example.sh):

trap "exit 0" TERM
top_pid=$$

evalInput(){

    cmd=$1

    if [[ $cmd =~ ^\ *exit\ *$ ]]; then
        kill -s TERM $top_pid
    elif [another command]
        ...
    fi
}

如果我输入evalInput "exit",则此过程将在退出状态为零时被终止。

测试文件:

testExitCmd(){
    . ./example.sh
    ...
    evalInput "exit"
    ps [PID of `evalInput` function]
    # `ps` command is failed if evalInput is killed. 
    assertNotEquals "0" "$?"
}

. shunit2

我测试evalInput函数的想法非常简单,只需使用ps命令确保evalInput函数被杀死但问题是我如何才能做到这一点?这里的重要问题是当您尝试执行evalInput时,这意味着您还会杀死testExitCmd函数

我已经尝试了很多方法,例如使用&evalInput放到另一个进程并bla bla bla。但我仍然收到shunit2:WARN trapped and now handling the (TERM) signal之类的错误。据我所知,这是我试图杀死我的测试功能过程的默认情况。

请仔细测试,我不认为只是你的想象力可以解决这个问题,但请测试一下代码。如果您在OSX,则只需通过shUnit2安装brew,然后只需./your_test_script.sh

运行即可

2 个答案:

答案 0 :(得分:1)

trap "exit 0" TERM
top_pid=$$

evalInput(){

    cmd=$1
    echo "CMD: $cmd"

    if [[ $cmd =~ ^\ *exit\ *$ ]]; then
        kill -s TERM $top_pid
    fi
}

testExitCmd(){
    evalInput "exit" &
    echo "Test evalInput"
    ps [PID of `evalInput` function]
    # `ps` command is failed if evalInput is killed. 
    assertNotEquals "0" "$?"
}

testExitCmd

输出

 Test evalInput
 CMD: exit

这有帮助吗?

答案 1 :(得分:1)

让我回答我自己的问题,我找到了一些棘手的方法,程序是

  1. 将目标程序生成为子进程并将其放到后台,
  2. 运行子进程然后停止1秒
  3. 在父进程中,将子进程的PID保存到文件tmp
  4. 子进程处于唤醒状态,然后从tmp$top_pid
  5. 读取PID
  6. 子进程现在知道它的PID,然后运行kill命令应该可以工作。
  7. 我的示例代码(example.sh):

    trap "exit 0" TERM
    top_pid=$$
    
    evalInput(){
    
        cmd=$1
    
        if [[ $cmd =~ ^\ *exit\ *$ ]]; then
            kill -s TERM $top_pid
        elif [another command]
            ...
        fi
    }
    

    如果我输入evalInput"退出"退出状态为零时,此过程将被终止。

    测试文件:

    testExitCmd(){
        (
            . ./example.sh
            sleep 1 # 1) wait for parent process save PID to file `temp`
            top_pid=`cat tmp` # 4) save PID to `top_pid`
            evalInput "exit" # 5) kill itself
        )&
        echo "$!" > tmp # 2) save PID of background process to file `tmp`
        sleep 2 # 3) wait for child process kill itself
        child_pid=$!
        ps $child_pid # `ps` command is failed if evalInput is killed. 
        assertNotEquals "0" "$?"
    }
    
    . shunit2