Batsというテストツールが便利だった

Batsというテストツールをしばしば見るので、使ってみたら便利だった。

github.com

シェルのコマンドのテストに使います。テストコードは、ほとんどBashDSLで書かれます。テストケースは以下のように書きます。

@test "echo hello" {
  out=$(echo hello)
  [ "$out" = "hello" ]
}

""内がテスト名で、[]で結果を比較する。

$ bats hello.bats 
 ✓ echo hello

1 test, 0 failures

TAP (Test Anything Protocol)で結果を出力することもできる。

$ bats hello.bats --tap
1..1
ok 1 echo hello

テストコードって乱立しがちだから、結果のフォーマットぐらいは揃えたい。その一つがTAPで、これで出力すればJenkinsとも連携したりできるよう。

XUnitでお馴染みのsetupとteardownも使える。

$ cat hello.bats 
setup() {
  echo "hello" > hello.txt
}

@test "cat hello" {
  out=$(cat hello.txt)
  [ "$out" = "hello" ]
}

teardown() {
  rm -f hello.txt
}
$ bats hello.bats 
 ✓ cat hello

1 test, 0 failures

runコマンドを使うと標準出力、標準エラー出力とexit codeが簡単に取れる。

$ cat hello.bats 
@test "echo hello" {
  run echo hello
  [ "$status" -eq 0 ]
  [ "$output" = "hello" ]
}
$ bats hello.bats 
 ✓ echo hello

1 test, 0 failures

$statusにexit codeが、$outputに標準出力と標準エラー出力を合わせたものが入れられる。

また出力が複数行に分かれる場合にはlines配列を見ると便利。

$ cat foobar.bats 
setup() {
  cat << END > foobar
foo
bar
baz
END
}

@test "cat foobar" {
  run cat foobar
  [ "$status" -eq 0 ]
  [ "${lines[0]}" = "foo" ]
  [ "${lines[1]}" = "bar" ]
  [ "${lines[2]}" = "baz" ]
}

teardown() {
  rm -f foobar
}
$ bats foobar.bats 
 ✓ cat foobar

1 test, 0 failures

skipコマンドでJUnit@Skip相当ができる。

$ cat skip.bats 
@test "skip" {
  skip
  [ 0 -eq 1 ]
}
$ bats skip.bats 
 - skip (skipped)

1 test, 0 failures, 1 skipped

テストの共通のコードを呼び出すのにはloadコマンドを使う。

$ cat helper.bash 
hello() {
  echo "hello"
}
$ cat load.bats 
load helper

@test "hello" {
  out=$(hello)
  [ "$out" = "hello" ]
}
$ bats load.bats 
 ✓ hello

1 test, 0 failures

非常にシンブルなので簡単に使えるし、シェルスクリプトをベタ書きしたようなテストコードより書きやすいし、保守もしやすいだろう。

試してはいないが、大きめのシステムテストになってくると、これだときつくなる気がする。システムテストのよいツールはないものだろうか。


追記:

いいのがないので自分でシステムテスト用のツールを作った.Bats との連携もいずれできるようにしたい.

GitHub - fjkz/tt-runner: A Test Scripts Runner