了解如何在 Exercism 上测试你的 Bash 练习
你可以在 Exercism 网站上使用在线编辑器来解答练习。或者,把练习下载到自己的电脑上,在本地解答后再提交到 Exercism。本文档的其余部分讲的是如何在本地操作。
你需要用exercism命令行工具来下载和提交练习。参见 exercism cli 文档。
默认的 exercism 工具有个烦人的地方:下载练习后,你得手动切换目录。这个包装函数能帮你处理这件事;把它存到~/.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
}
注意,它不能是 shell 脚本,必须是 shell 函数。Shell 脚本在子进程里执行,无法影响当前 shell 的环境(比如当前工作目录)。
bash 赛道上的测试使用的是 bats。
对于假设的“whatever”练习,可以像这样运行测试:
cd /path/to/your/exercise_workspace/bash/whatever
bats whatever.bats
如果你想在本地运行测试时打印调试输出,请参见 在本地调试。
bats-core
你应该可以从常用的包管理器里安装它:
在 macOS 上使用 Homebrew,大致是这样:
$ 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包。千万别装错:要安装bats-core。bats已经为 Fedora 30 及更新版本打包,可以用下面的命令安装:
sudo dnf install bats
对于其他 Linux 发行版,我们所用的bats实现可能没有现成的软件包。最好的办法是从源码安装。如果你想把它装到/usr/local下,那就
git clone https://github.com/bats-core/bats-core
cd bats-core/
sudo ./install.sh /usr/local
之后,假设/usr/local/bin在你的 $PATH 里,现在就可以这样做:
$ 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
注意:如果你用的是过时的https://github.com/sstephenson/bats.git,又遇到类似cp: cannot create symbolic link '${HOME}/bin/bats': No such file or directory这样的错误,那就得手动把bin/bats/libexec/文件夹里的内容复制到${HOME}/bin/。
有报告称较新的 bats 版本在 MinGW bash 上表现不佳,所以在运行安装脚本前,你可能想先:
$ git checkout v1.1.0
想了解测试里各种assert*命令的含义,请参考 bats-assert 库的文档。
解答一道练习,意味着让它所有的测试都通过。默认情况下,运行测试时只会执行一个测试(第一个)。这是有意设计的,这样你就能专心先让那一个测试通过。一旦它通过,你就可以通过注释掉或删除下面这行,来启用下一个测试:
[[ $BATS_RUN_SKIPPED == true ]] || skip
这行注解加在其他测试的前面。
要运行所有测试(包括带skip注解的测试),你可以把环境变量BATS_RUN_SKIPPED的值设为true。一种只在运行 bats 期间设置它的方式是:
BATS_RUN_SKIPPED=true bats exercise_name.bats
用包装函数来省点打字会很方便:
bats() {
BATS_RUN_SKIPPED=true command bats *.bats
}
之后只需这样运行测试:
bats
bats
bats-core是从最初的bats实现分叉而来的。sstephenson/bats项目 bug 很多,而且已经被弃置了。项目所有权在 2017 年移交了出去:sstephenson/bats#150(评论)。
如果你装的是原本的 sstephenson/bats(可以用bats -v查看,如果报告的版本号低于 1.0),那就该换成 bats-core;否则你可能会遇到莫名其妙的测试失败。