lundi 5 avril 2021

BATS assert_failure in nested function

Context

While writing a test that expects an exception/error to be thrown, I am experiencing some difficulties detecting the error.

The code installs various software packages and tests each installation command separately. 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. For completenes, the code of run_main_functions consists of:

#!/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
}

This run_main_functions then calls a function count_nr_of_lines which I expect to throw an error if it is fed an invalid filepath. It consists of:

#!/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 "$@"

And the test that checks whether the count_nr_of_lines throws an error if the INPUT_PATH is of a non-existant filepath is:

#!./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"
}

Where the filepath to the non-existant file is fed as:"test/testfiles/nonexistant_filename.txt". The test fails with error:

✗ 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

So in some sense, an error is thrown, which is expected, but I would expect the bats test to catch that error/exception, and yield a passed test.

Question

How could I make the bats test succesfully catch the error that is thrown if the file does not exist?

Attempts

I also tried to include an invalid path detection inside the count_nr_of_lines function with:

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

to throw an explicit error, however, that removes the verbosity/error messages from the test failure and only results in a failing test.

Aucun commentaire:

Enregistrer un commentaire