嵌套函数中的 BATS assert_failure
BATS assert_failure in nested function
上下文
在编写预期抛出 exception/error 的测试时,我在检测错误时遇到了一些困难。
代码安装各种软件包并分别测试每个安装命令。有一个函数在每个函数之前做一些预处理,然后调用安装函数,这个管理函数叫做:run_main_functions
,如果输入参数,它会传递参数。对于completenes,run_main_functions
的代码包括:
#!/bin/bash
run_main_functions() {
local SCRIPT_NAME=
local EXTRA_ARGUMENT=
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
然后调用一个函数 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=
local INPUT_PATH=
# 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 测试能够捕捉到 error/exception,并产生 passed test
.
问题
如何通过 catching/registering 文件不存在时抛出的错误使 bats
测试成功通过?
尝试次数
我还尝试在 count_nr_of_lines
函数中包含无效路径检测:
if [ ! -f "$INPUT_PATH" ] ; then
exit 1
fi
抛出一个明确的错误,但是,这会从测试失败中删除 verbosity/error 消息,只会导致测试失败。
我不明白你为什么 运行 设置中的测试代码。这个怎么样
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 returns OK,或者使用 the run
command
会出错
run run_main_functions
expect_failure
我 认为 会起作用,但我对必须导出源函数有一个模糊的记忆(虽然我找不到关于那个 in the docs 的任何参考)
并且在重新阅读文档后,使用 setup_file
:
而不是 setup
setup_file() {
echo "# Testfile: $(basename ${BATS_TEST_FILENAME})-" >&3
}
glenn jackman 的回答确实导致了一个可行的解决方案。根据我的实验,主要问题是 assert_failure
应该直接跟在应该失败的 line/command 之后。因此,当我将该行放在 setup()
或 setup_file()
中时,情况并非如此。因此,我将 run run_main_functions ..
命令移到实际测试中并添加了 run
.
此外,为了验证 运行 命令本身没有错误,即被捕获,我验证了在测试文件中执行相同命令时测试 assert_failure
失败在向测试函数提供文件路径时 确实 存在。
在正在测试的函数中,我可以使用 exit 1
抛出错误,并且该错误被测试成功捕获。
功能代码如下:
#!/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=
# 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
}
上下文
在编写预期抛出 exception/error 的测试时,我在检测错误时遇到了一些困难。
代码安装各种软件包并分别测试每个安装命令。有一个函数在每个函数之前做一些预处理,然后调用安装函数,这个管理函数叫做:run_main_functions
,如果输入参数,它会传递参数。对于completenes,run_main_functions
的代码包括:
#!/bin/bash
run_main_functions() {
local SCRIPT_NAME=
local EXTRA_ARGUMENT=
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
然后调用一个函数 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=
local INPUT_PATH=
# 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 测试能够捕捉到 error/exception,并产生 passed test
.
问题
如何通过 catching/registering 文件不存在时抛出的错误使 bats
测试成功通过?
尝试次数
我还尝试在 count_nr_of_lines
函数中包含无效路径检测:
if [ ! -f "$INPUT_PATH" ] ; then
exit 1
fi
抛出一个明确的错误,但是,这会从测试失败中删除 verbosity/error 消息,只会导致测试失败。
我不明白你为什么 运行 设置中的测试代码。这个怎么样
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 returns OK,或者使用 the run
command
run run_main_functions
expect_failure
我 认为 会起作用,但我对必须导出源函数有一个模糊的记忆(虽然我找不到关于那个 in the docs 的任何参考)
并且在重新阅读文档后,使用 setup_file
:
setup
setup_file() {
echo "# Testfile: $(basename ${BATS_TEST_FILENAME})-" >&3
}
glenn jackman 的回答确实导致了一个可行的解决方案。根据我的实验,主要问题是 assert_failure
应该直接跟在应该失败的 line/command 之后。因此,当我将该行放在 setup()
或 setup_file()
中时,情况并非如此。因此,我将 run run_main_functions ..
命令移到实际测试中并添加了 run
.
此外,为了验证 运行 命令本身没有错误,即被捕获,我验证了在测试文件中执行相同命令时测试 assert_failure
失败在向测试函数提供文件路径时 确实 存在。
在正在测试的函数中,我可以使用 exit 1
抛出错误,并且该错误被测试成功捕获。
功能代码如下:
#!/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=
# 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
}