HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashMinor

Unit testing a bash script manipulating the working directory path

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
scriptdirectorythepathmanipulatingworkingtestingbashunit

Problem

bd is a bash script to conveniently jump multiple directory levels up from the current working directory instead of a tedious and possibly inaccurate cd ../../../..

Say, for example, that you are in the directory /home/user/project/src/org/main and you want to jump to project. Instead of counting the necessary levels to jump and typing cd ../../.., you can do bd -s pro (where -s is to match the start of the directory name, in this example "pro" for "project").

I came across this script in another question, and looking at the github repository I decided to jazz it up a little. But before going ahead and refactoring it, I wanted to make sure I'm not breaking anything, so I needed some sort of unit tests as a sane baseline first.

This is the main function in the bd script under testing,
and this is not for code review,
I'm including it here only for your reference in case it helps in some way:

# NOT for code review: the reference implementation under test
newpwd() {
  OLDPWD=$1
  if [ "$2" = "-s" ]
  then
    NEWPWD=`echo $OLDPWD | sed 's|\(.*/'$3'[^/]*/\).*|\1|'`
    index=`echo $NEWPWD | awk '{ print index($0,"/'$3'"); }'`
  elif [ "$2" = "-si" ]
  then
    NEWPWD=`echo $OLDPWD | sed 's|\(.*/'$3'[^/]*/\).*|\1|I'`
    index=`echo $NEWPWD | awk '{ print index(tolower($0),tolower("/'$3'")); }'`
  else
    NEWPWD=`echo $OLDPWD | sed 's|\(.*/'$2'/\).*|\1|'`
    index=`echo $NEWPWD | awk '{ print index($1,"/'$2'/"); }'`
  fi
}


What I'd like reviewed is my implementation of "unit tests" to verify the behavior of the newpwd function inside the bd script:

```
#!/bin/bash

# loading the "newpwd" function from the bd script, a necessary ugliness for now
. bd nonexistent > /dev/null

success=0
failure=0
total=0

assertEquals() {
((total++))
expected=$1
actual=$2
if [[ $expected = $actual ]]; then
((success++))
else
((failure++))
echo "Assertion failed: $expected != $actual" >&2
caller 0

Solution

Just 2 cents:

-
I'd quote the right hand side of the [[ ... = ... ]] to avoid pattern interpretation. Cf.

x=123
y=*2*
[[ $x =  $y  ]] && echo Equal without quotes
[[ $x = "$y" ]] || echo Not equal with quotes


-
I like naming the tests. I'd probably add a third parameter to assertEquals and include it in the report. It also improves readability. Inspired by Test::More for Perl.

Code Snippets

x=123
y=*2*
[[ $x =  $y  ]] && echo Equal without quotes
[[ $x = "$y" ]] || echo Not equal with quotes

Context

StackExchange Code Review Q#65169, answer score: 2

Revisions (0)

No revisions yet.