Unusual Unit testing (part 1) — Bash scripts with Bats

Introduction

Unit testing Bash scripts with Bats

Testable code anyone?

Let’s get started — preparation

FROM bats/bats:latest 
COPY ./temp_clone_dir /opt/bats-test-helpers
WORKDIR /code/
[ -d "temp_clone_dir" ] && rm -rf "temp_clone_dir"
mkdir temp_clone_dir
git clone https://github.com/ztombol/bats-support temp_clone_dir/bats-support
git clone https://github.com/ztombol/bats-assert temp_clone_dir/bats-assert
git clone https://github.com/lox/bats-mock temp_clone_dir/lox-bats-mock
docker build . -t bats-with-helpers:latest

Test 1 — assert the return of a function

# example1.shfunction func1() {
return 1
}
# test_example1.bats
#!/usr/bin/env bats
@test "func1 function should return 1" {
source /code/example1.sh
run func1
[ "$status" -eq 1 ]
}
@test "func1 function should return 2" {
source /code/example1.sh
run func1
[ "$status" -eq 2]
}

Test 2 — test a condition and a file mutation

function func2() {
if [ ${ENV_GRASS} = "green" ]
then
touch colors.conf
echo 'grass="green"' > colors.conf
fi
}
# test_example1.bats
#!/usr/bin/env bats
load '/opt/bats-test-helpers/bats-support/load.bash'
load '/opt/bats-test-helpers/bats-assert/load.bash'
@test "func2 function should create config file is grass is green" {
source example1.sh
ENV_GRASS="green"
run func2
assert [ -e 'colors.conf' ]
}
@test "func2 function should not create config file if grass is not green" {
source example1.sh
ENV_GRASS="red"
run func2
assert [ ! -e 'colors.conf' ]
}

Test 3 — test a terraform wrapper script

init_tf() {
if [ -d ".terraform" ]; then
echo "unclean working dir, .terraform dir still exists. removing .terraform"
rm -rf .terraform
fi
terraform init -input=false
}
# test_example_tf_plan.bats
#!/usr/bin/env bats
load '/opt/bats-test-helpers/bats-support/load.bash'
load '/opt/bats-test-helpers/bats-assert/load.bash'
load '/opt/bats-test-helpers/lox-bats-mock/stub.bash'
setup() {
stub terraform \
"'init -input=false' : echo 'I am stubbed for terraform init!'"
if [ -d .terraform ] ; then rm -rf .terraform ; fi
}
@test "init_tf function should remove dir .terraform if exists" {
source example_tf_plan.sh
mkdir .terraform
run init_tf
assert [ ! -d '.terraform' ]
}
@test "init_tf function should print message if dir. .terraform exists" {
source example_tf_plan.sh
mkdir .terraform
run init_tf
assert_output "unclean working dir, .terraform dir still exists. removing .terraform"
}

Conclusion

DevOps coach, AWS Cloud consultant. People > Processes > Technology.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store