moritetuのIT関連技術メモ

bats

Bashで書かれたテストツールで、unixプログラムの振る舞いをチェックするために有用である。
コマンドラインから実行できるプログラムの動作確認として幅広く使うことができる。

何といっても非常に小さなプログラムで軽量であるのが特徴である。
Bashなので、大抵のUnix/Linux環境で何も特別なライブラリを必要とせず導入できる。

インストール

非常に簡単で、install.shを実行するのみである。
install.shの引数で指定されたPREFIXにbatsがインストールされる。
他manもインストールされるので、man batsでマニュアルを確認できる。

$ git clone https://github.com/sstephenson/bats.git
$ bash ./bats/install.sh /usr/local
Installed Bats to /usr/local/bin/bats
$ bats
Bats 0.4.0
Usage: bats [-c] [-p | -t] <test> [<test> ...]
$ man bats

テスト

bats自体のテストがbatsで書かれているので、お手本はbatsのテストプログラムを見ればよい。

https://github.com/sstephenson/bats/tree/master/test

テストプログラム

例1 sample.bats

#!/usr/bin/env bats

# This is a sample test program with bats.

@test "Here is the title of the test" {
    # This is a test program
    run echo "hoge"
    [ $status -eq 0 ]
}

実行してみよう。

$ bats sample.bats
 ✓ Here is the title of the test

1 test, 0 failures

テストスイートの実行

batsコマンドにディレクトリを指定すると、ディレクトリ下の.batsファイルを順に実行してくれる。
テストは、glob(*.bats)にマッチするファイルが対象であり、実行順は特に意識されない。
また、検索対象は指定されたディレクトリ階層下であり、2階層以上にのファイルは対象ではない。

$ tree tests
tests
├── bar.bats
└── foo.bats

0 directories, 2 files
$ bats tests
 ✓ test2
 ✓ test1

2 tests, 0 failures

実行環境

setup、teardown

各テスト実行前にsetup、テスト終了時にteardownを実行できる。
プリプロセスで変換されたテスト関数を見ると、テストプログラムの前にsetup関数が呼ばれることがわかる(bats_test_begin)。teardownは、exit trapで実行される。

setup, teardownの例

#!/usr/bin/env bats

setup() {
  TEST_DATA="test"
}

teardown() {
  : nothing
}

@test "test2" {
  [ "$TEST_DATA" = "test" ]
}

@test "test3" {
  [ "$TEST_DATA" = "test" ]
}

実行結果は以下のとおり。

$ bats bar.bats
 ✓ test2
 ✓ test3

2 tests, 0 failures

ヘルパー

必要な機能やデータは、loadコマンドでインクルードできる。
これは、sourceコマンドのラッパーである。
ファイルパスは、絶対パスまたはテスト対象ファイルからの相対パスである。

インクルードするファイルは、拡張子が.bashであることを期待している。

$ cat my.bash
ENVIRONMENT=dev
$ cat helper.bats
load my

@test "Load test" {
  [ "$ENVIRONMENT" = "dev" ]
}
$ bats helper.bats
 ✓ Load test

1 test, 0 failures

テスト内で使用できる変数

runコマンドで実行したコマンドの内容は、以下の変数で参照できる。

変数名説明
output標準出力、標準エラー出力(標準出力にリダイレクトされる)
linesoutputの\n区切りの配列
status終了ステータス

その他

テスト時のカレントディレクトリは、テスト実行した$PWDである。
ファイルを作成したり、rmしたりする場合は注意して意識して行なうのが良い。

プリプロセス

batsは、テスト実行前に一度変換プロセスを挟むと前章で説明した。
具体的にどのようなファイルが作成されるか、参考までに以下で見てみる。

プリプロセスを実行しているbats-preprocessを実行してみよう。
先ほどの例1のsample.batsをプリプロセスにかけると以下のように変換されていることが分かる。
現在の実行コンテキストがどうなっているのか、以下の結果から判断することができる。
例えば、@testの内部やファイルの内部で定義した変数の可視範囲、影響範囲は?といった内容である。

sample.batsのプリプロセスの結果

# sample.bats
@test "Here is the title of the test" {
    # echo "my message"は一度キャプチャされる
    echo "my message"
    run echo "hoge"
    [ $status -eq 0 ]
}

bats_test_functionは、引数で指定される関数をテスト関数として登録する。
また、このファイルは別プロセス(サブシェル)で関数実行毎にsourceコマンドでインクルードされる。
よって、同一ファイルの複数のテストに渡って引き継ぎしたい変数は、テストファイルの@test { } の外のコンテキストで定義しておけばよい。
そして、@test {} の中で実行される内容はサブシェルで実行されるため、あるテスト関数内で定義した変数は、他のテスト関数に影響しない。

例2 sample2.bats

@test "Here is the title of the test" {
    echo "my message"
    run echo "hoge"
    [ $status -eq 1 ]
}

実行した結果は、以下のとおりである。

$ bats sample.bats
 ✗ Here is the title of the test
   (in test file sample.bats, line 8)
     `[ $status -eq 1 ]' failed
   my message

1 test, 1 failure

メモ ソースファイルはN+1回実行される?

sample2.batsのグローバルコンテキスト(ここでは、@testブロックの外のこととする)にecho "included"を仕掛けて実行した場合、以下のようになる。
includedという文字が3回出力されている。テスト数+1回評価されていることが分かる。

@test "Here is the title of the test" {
    echo "my message" >&3
    run echo "hoge"
    [ $status -eq 0 ]
}

関連

参考リンク


トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
目次
ダブルクリックで閉じるTOP | 閉じる
GO TO TOP