Bash: pretty pass/fail lines

2022-12-06
#howto

I find myself writing a lot of one-off tests in bash.

If there are multiple checks happening within a single script, parsing the output from the terminal to figure out what exactly failed can become tedious pretty quickly. In fact, I usually don't care about each command's output. I just want to know if it passed or failed.

A "run_test" command

For those of you in a similar boat, here is a little ditty to tickle your fancy:

green() {
	local text=$1
	printf "\x1b[1;92m$text\x1b[0m"
}

red() {
	local text=$1
	printf "\x1b[1;91m$text\x1b[0m"
}

run_test() {
	local cmd="$@"
	eval $cmd >/dev/null 2>&1
	if [ $? -eq 0 ]; then
		echo "$(green [pass])" $cmd
	else
		echo "$(red [fail])" $cmd
	fi
}

Any command that returns a non-zero exit code will flag a failure in bright red, so it's impossible to miss.

Example

Here are some very basic acceptance tests I wrote for a web app.

opts="--connect-timeout 2 --silent -I -L"
url="localhost:8000"

is_live() {
	local response=$(curl $opts $url)
	echo "$response" | grep HTTP | grep 200
}

can_authenticate() {
  ...
}

run_test is_live
run_test can_authenticate

A bright-red failure in the terminal:

And that sweet green of victory...

Note: make sure to remove set -o errexit if you enabled that anywhere.

Cheers!

~ Rex