Learn how to test your Bash exercises on Exercism
You can use the online editor on the Exercism website to solve the exercises. Or, download the exercises to your computer, solve them locally and then submit them to Exercism. The rest of this document talks about working locally.
You will need the exercism
command-line tool to download and submit exercises.
See the exercism cli documentation.
One annoying aspect of the default exercism tool is that, after you download an exercise, you have to change directory manually.
This wrapper function handles that for you; store this in your ~/.bashrc
.
exercism () {
local out
readarray -t out < <(command exercism "$@")
printf '%s\n' "${out[@]}"
if [[ $1 == "download" && -d "${out[-1]}" ]]; then
cd "${out[-1]}" || return 1
fi
}
Note that cannot be a shell script, it must be a shell function. Shell scripts are executed in a child process and cannot effect the environment (like the current working directory) of your current shell.
For testing on the bash track, we are using bats.
Run the tests for the hypothetical "whatever" exercise like this:
cd /path/to/your/exercise_workspace/bash/whatever
bats whatever.bats
bats-core
You should be able to install it from your favorite package manager:
On macOS with Homebrew this would look something like this:
$ brew install bats-core
==> Downloading https://github.com/bats-core/bats-core/archive/v1.1.0.tar.gz
==> Downloading from https://codeload.github.com/bats-core/bats-core/tar.gz/v1.1.0
######################################################################## 100.0%
==> ./install.sh /usr/local/Cellar/bats-core/1.1.0
🍺 /usr/local/Cellar/bats-core/1.1.0: 13 files, 55KB, built in 4 seconds
bats
package also exists in the homebrew ecosystem.
Do not install that by mistake: install bats-core
.bats
is packaged for Fedora 30 and newer, you can install it with
sudo dnf install bats
For other Linux distributions the implementation of bats
we use may not be conveniently packaged.
The best way to install it is from source.
If you want to install it under /usr/local
then
git clone https://github.com/bats-core/bats-core
cd bats-core/
sudo ./install.sh /usr/local
Following that, assuming /usr/local/bin
is in your $PATH, you can now do:
$ bats
Error: Must specify at least one <test>
Usage: bats [-cr] [-f <regex>] [-j <jobs>] [-p | -t] <test>...
bats [-h | -v]
...
$ git clone https://github.com/bats-core/bats-core.git
$ cd bats-core
$ ./install.sh $HOME
Note: When you are using the outdated https://github.com/sstephenson/bats.git
and you discover an error like cp: cannot create symbolic link '${HOME}/bin/bats': No such file or directory
, you have to copy the bin/bats/libexec/
folder content to ${HOME}/bin/
manually.
There are reports that newer bats versions don't behave well on MinGW bash -- before you run the install script, you might want to:
$ git checkout v1.1.0
For help on the meaning of the various assert*
commands in the tests, refer to the documentation for the bats-assert library.
Solving an exercise means making all its tests pass. By default, only one test (the first one) is executed when you run the tests. This is intentional, as it allows you to focus on just making that one test pass. Once it passes, you can enable the next test by commenting out or removing the
[[ $BATS_RUN_SKIPPED == true ]] || skip
annotations prepending other tests.
To run all tests, including the ones with skip
annotations, you can set an environment variable BATS_RUN_SKIPPED
to the value true
.
One way to set this just for the duration of running bats is:
BATS_RUN_SKIPPED=true bats exercise_name.bats
It can be convenient to use a wrapper function to save on typing:
bats() {
BATS_RUN_SKIPPED=true command bats *.bats
}
Then run tests with just:
bats
bats
bats-core
was forked from the original bats
implementation.
The sstephenson/bats
project was quite buggy and had been abandoned.
Ownership was handed over in 2017: sstephenson/bats#150 (comment).
If you have the original sstephenson/bats installed (check with bats -v
reporting a version number less than 1.0), then you should switch to bats-core; otherwise you may find yourself experiencing unexplained test failures.