Bats で bash(シェルスクリプト) のテストを書く
※記事を書いて公開するまで1年くらい経っているので情報が古い可能性があります。
Bats(Bash Automated Testing System)は、bash のテスティングフレームワークです。sstephenson/bats · GitHub
Test Kitchen(Bussser) の Bats plugin で使うことができるのでご存知の方も多いと思います。
簡単に使い方を説明すると、
@test "テストの説明" { command ... }
という記法でテストを記述し、コマンドの返り値が 0 ならテストをパスします。
以下のようにスクリプトを実行してテストをすることができます。
$ bats test.bats
インストール
インストール方法は、以下のとおりです。
sudo add-apt-repository ppa:duggan/bats --yes sudo apt-get update -qq sudo apt-get install -qq bats
brew install bats
- その他
git clone https://github.com/sstephenson/bats.git cd bats ./install.sh /usr/local
テストの書き方
テストコードと実行結果は、以下のようになります。
- テストコード
- 実行結果
テストコードを元に上から順に説明していきます。
setup, teardown
- setup
- 各テストの実行前に実行される処理を関数として定義
- teardown
- 各テストの実行後に実行される処理を関数として定義
となります。
コード内で、BATS_ から始まる変数が使われていますが、
これらは Bats の特殊変数です。
詳細は後述します。
run, $status, $output, $lines
run FILEPATH で外部スクリプトを実行すると、
$status, $output, $lines に値がセットされます。
各変数は以下のとおりです。
- $status
- $output
- 標準出力
- $lines
- 標準出力を行ごとに配列に格納
以下のスクリプトだと、
status=1 output=foobar lines[0]=foobar
になります。
lines については配列なので、出力が 2 行の場合は lines[1] に 2 行目の出力結果が格納されます。
skip
skip は、文字通りテストをスキップします。
load
load は、外部スクリプトを読み込みます。
load の引数となるファイルパスを書く場合は 2 つの注意点があります。
特殊変数
以下の実行結果から、それぞれの変数の値を見ていくと、
- BATS_TEST_NAME
- テストの説明部分を test_ prefix と、半角スペースを _ に変換したもの
- BATS_TEST_FILENAME
- 実行している Bats ファイルのフルパス
- BATS_TEST_DIRNAME
- Bats ファイルを配置しているディレクトリ
- BATS_TEST_NAMES
- BATS_TEST_NAME を 0 から始まる配列に格納
- BATS_TEST_DESCRIPTION
- テストの説明部分
- BATS_TEST_NUMBER
- テストの番号
となっていることがわかります。
また、実行結果を見ると、
setup -> テスト -> teardown と実行されていることが確認できます。
テスト外のコードについて
@test, setup, teardown 関数の外で標準出力をするコードを書いた場合、
>&2 で標準エラー出力にリダイレクトするようにしないと、
TAP の標準出力を汚染してテストが失敗する可能性があるようです。