繁体   English   中英

嵌套 function 中的 BATS assert_failure

[英]BATS assert_failure in nested function

语境

在编写期望抛出异常/错误的测试时,我在检测错误时遇到了一些困难。

该代码安装各种软件包并分别测试每个安装命令。 There is one function that does some preprocessing before each function and then calls the installation function, this managing function is called: run_main_functions , and it passes along arguments if they are entered. 为了完整起见, run_main_functions的代码包括:

#!/bin/bash
run_main_functions() {
    local SCRIPT_NAME=$1
    local EXTRA_ARGUMENT=$2
    SCRIPT_PATH=src/"$SCRIPT_NAME".sh
    local LOG_PATH=$LOG_LOCATION"$SCRIPT_NAME".txt
    
    chmod +x $SCRIPT_PATH
    
    # Remove old log files if exist
    if [ -f "$LOG_PATH" ] ; then
        rm "$LOG_PATH"
    fi
    
    # run the function that performs a single installation command
    if [ "$EXTRA_ARGUMENT" == "" ]; then
        source ./$SCRIPT_PATH $LOG_PATH
    else
        source ./$SCRIPT_PATH $LOG_PATH $EXTRA_ARGUMENT
    fi
}

然后这个run_main_functions调用一个 function count_nr_of_lines如果它被输入一个无效的文件路径,我希望它会抛出一个错误。 它包括:

#!/bin/bash
# Count the total nr of lines in an incoming file and export it.
count_nr_of_lines() {
    source src/hardcoded_variables.txt
    
    local LOG_PATH=$1
    local INPUT_PATH=$2
    
    # read content from file
    text_content=$(<$INPUT_PATH)
    
    # count the number of lines in that app
    total_nr_of_lines=$(echo "$text_content" | wc -l)
    
    # 4. Write the result of the content check to a log file.
    echo $total_nr_of_lines > "${TOTAL_NR_OF_LINES_IN_TARGET_FILEPATH}"
}
count_nr_of_lines "$@"

如果INPUT_PATH是不存在的文件路径,则检查count_nr_of_lines是否引发错误的测试是:

#!./test/libs/bats/bin/bats

load 'libs/bats-support/load'
load 'libs/bats-assert/load'
load 'libs/bats-file/load'

source test/helper.sh
source src/hardcoded_variables.txt
source src/helper.sh

mkdir -p src/logs

# Method that executes all tested main code before running tests.
setup() {
    
    # print test filename to screen.
    if [ "${BATS_TEST_NUMBER}" = 1 ];then
        echo "# Testfile: $(basename ${BATS_TEST_FILENAME})-" >&3
    fi
    
    # Declare filenames of files that perform commands
    declare -a script_names=("custom_install_4_energizedprotection")
    
    # Specify an additional array with arguments
    declare -a additional_arguments=("test/testfiles/nonexistant_filename.txt")

    # Loop through files that perform commands
    for i in "${!script_names[@]}"; do
        run_main_functions "${script_names[i]}" "${additional_arguments[i]}"    
    done
}

#---------------------------------------------------------------------------------------------------------------------------
@test "Tests whether an exception is thrown when computing the total nr of lines, if the file is not found." {
    ACTUAL_RESULT=$(<$TOTAL_NR_OF_LINES_IN_TARGET_FILEPATH)
    EXPECTED_OUTPUT="1"

    assert_failure
    #assert_equal "$ACTUAL_RESULT" "$EXPECTED_OUTPUT"
}

不存在文件的文件路径输入为: "test/testfiles/nonexistant_filename.txt" 测试失败并出现错误:

✗ Tests whether an exception is thrown when computing the total nr of lines, if the file is not found.
   (from function `apt_update' in file ./src/custom_install_4_energizedprotection.sh, line 10,
    from function `source' in file ./src/custom_install_4_energizedprotection.sh, line 18,
    from function `run_main_functions' in file src/helper.sh, line 19,
    from function `setup' in test file test/test_custom_install_4_1_energizedprotection.bats, line 28)
     `run_main_functions "${script_names[i]}" "${additional_arguments[i]}"' failed
   ./src/custom_install_4_energizedprotection.sh: line 10: test/testfiles/nonexistant_filename.txt: No such file or directory

所以在某种意义上,会抛出一个错误,这是意料之中的,但我希望 bats 测试能够捕捉到那个错误/异常,并产生一个passed test

问题

如果文件不存在,我如何通过捕获/注册引发的错误来成功通过bats测试?

尝试

我还尝试在count_nr_of_lines function 中包含无效路径检测:

if [ ! -f "$INPUT_PATH" ] ; then
    exit 1
fi

但是,抛出一个显式错误会从测试失败中删除详细/错误消息,并且只会导致测试失败。

我不明白你为什么在设置中运行测试代码。 这个怎么样

setup() {
    # print test filename to screen.
    if [ "${BATS_TEST_NUMBER}" = 1 ];then
        echo "# Testfile: $(basename ${BATS_TEST_FILENAME})-" >&3
    fi
}

#---------------------------------------------------------------------------------------------------------------------------
@test "Tests whether an exception is thrown when computing the total nr of lines, if the file is not found." {
    #ACTUAL_RESULT=$(<$TOTAL_NR_OF_LINES_IN_TARGET_FILEPATH)
    #EXPECTED_OUTPUT="1"

    # this will report an error if it has a non-zero return status
    run_main_functions "custom_install_4_energizedprotection" "test/testfiles/nonexistant_filename.txt"

    #assert_equal "$ACTUAL_RESULT" "$EXPECTED_OUTPUT"
}

我错过了您明确期望失败的观点。 你可以

    ! run_main_functions ...

如果 run_main_functions 返回 OK 会出错,或者使用run命令

    run run_main_functions
    expect_failure

认为这会起作用,但我对必须导出源函数有一个模糊的回忆(虽然我在文档中找不到任何关于它的参考)


在重新阅读文档后,而不是setup使用setup_file

setup_file() {
    echo "# Testfile: $(basename ${BATS_TEST_FILENAME})-" >&3
}

格伦杰克曼的回答确实导致了一个可行的解决方案。 根据我的实验,主要问题是assert_failure应该直接跟随应该失败的行/命令。 因此,当我将该行放入setup()setup_file()时,情况并非如此。 因此,我将run run_main_functions..命令移到实际测试中并预先添加run

此外,为了验证运行命令本身没有错误,我验证了当在测试文件中执行相同的命令时测试assert_failure失败,同时为测试的 function 提供指向确实存在的文件的文件路径.

在正在测试的 function 中,我可以使用exit 1抛出错误,并且该错误被测试成功捕获。

这是 function 代码:

#!/bin/bash


# Count the total nr of lines in an incoming file and export it.
count_nr_of_lines() {
    
    # Receive a filepath for which the amount of lines that it contains, is exported to a log file.
    local INPUT_PATH=$2
    
    # Throw an error with exit status 1 if the file does not exist.
    if [ ! -f "$INPUT_PATH" ] ; then
        exit 1
    fi
    
    # Read content from the input file.
    text_content=$(<"$INPUT_PATH")
    
    # Count the number of lines in that file.
    total_nr_of_lines=$(echo "$text_content" | wc -l)
    
    # Write the result of the content check to a log file.
    echo "$total_nr_of_lines" > "${TOTAL_NR_OF_LINES_IN_TARGET_FILEPATH}"
}


# Ensures this script executes the function above.
count_nr_of_lines "$@"

这是我最终使用的测试代码:

#!/bin/bash

# Load bats testing packages
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
load 'libs/bats-file/load'

# Load hardcoded variables and helper functions.
source src/hardcoded_variables.txt
source src/helper.sh
source test/helper.sh

# Create the path to the log file folder.
mkdir -p src/logs

# Method that executes all tested main code before running tests.
setup_file() {
    
    # print test filename to screen.
    if [ "${BATS_TEST_NUMBER}" = 1 ];then
        echo "# Testfile: $(basename "${BATS_TEST_FILENAME}")-" >&3
    fi
}


#-----------------------------------Test execution of custom_install_4_energizedprotection.sh-----------------------------------------------
@test "Tests whether an exception is thrown when computing the total nr of lines, if the file is not found ERRROR." {
    # The test passes based if the assert failure directly follows this command (which throws an error because the file is not found).
    run run_main_functions "custom_install_4_energizedprotection" "test/testfiles/nonexistant_filename.txt"
    
    # The test fails if the assert failure directly follows this (working) command. 
    #run run_main_functions "custom_install_4_energizedprotection" "test/testfiles/hostfile_with_social_pack.txt"
    
    # Expect the command to fail when it is passed a path to a file that does not exist.
    assert_failure
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM