tkuchikiの日記

Linux やプログラミングについて書きます。

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=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 の標準出力を汚染してテストが失敗する可能性があるようです。

まとめ

サンプルのテストコードを元に、Bats の使い方を説明しました。

スクリプトの実行ステータスや標準出力のチェックを行う用途であれば、
bash 以外のテストも行えるので色々な用途に利用できるのではないかと思います。