Bats is great for testing bash scripts, but its documentation is severely lacking in many areas1, including examples and explanations.
I am trying to write a test for a function I've written. However, because the result of this function is a global array, it seems Bats is unable to see it. (This problem may also exist for normal variables, but I could export their contents via stdout
.)
#!bats/bin/bats
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
_load_filetoarray() {
# Imagine the source of array data is an external file
declare -a CREATEDARRAY
CREATEDARRAY=("aaa" "bbb" "ccc")
export CREATEDARRAY
}
@test "stackoverflow plain" {
# Run function that is tested.
run _load_filetoarray
# Ensure correct number of lines got loaded
assert [ "${#CREATEDARRAY[@]}" -eq 3 ]
}
The above file, which provides both the function definition (_load_filetoarray
) and the test, produces the below output on Bats v1.10.0.
stackoverflow.bats
✗ stackoverflow plain
(from function `assert' in file test_helper/bats-assert/src/assert.bash, line 40,
in test file stackoverflow.bats, line 18)
`assert [ "${#CREATEDARRAY[@]}" -eq 3 ]' failed
-- assertion failed --
expression : [ 0 -eq 3 ]
--
1 test, 1 failure
If I declare the same function in a separate bash script and run it myself, it works just fine and the array is obviously loaded. But Bats doesn't seem to be able to see the array.
How can I get Bats to see the array so I can write the unit test to verify that I've written the function correctly?
1 Rant about Bats documentation
I'm sorry, it's a great tool, but the documentation is giving me flashbacks to the Bad Old Days of computing, when knowledge was gatekept by Greybeards. It took me YEARS to discover that Bats allowed direct testing of functions, and I only found that out by seeing someone else's test file. I had to back my way into one test that required run bash -c '...'
with export -f funcname
. Which came first, $lines
or $output
, because one must be derived from the other and that derivation could lead to problems so I'd like to know. Oh, and the official readthedocs.io tutorial goes incoherent in the middle and starts referencing files that weren't previously introduced.
Global arrays or other global variables are better avoided. Pass the output array to your function by “reference” (nameref) instead.
The output:
Stating the obvious, one can now reference
f
from abats
test and have it modify variables: