独特のクセがある。パス絡みで使いづらい。
Bats
ダウンロード&インストール
$ git clone https://github.com/sstephenson/bats.git $ cd bats $ sudo ./install.sh /usr/local Installed Bats to /usr/local/bin/bats
使ってみる
テストコードを書いてみる。
A.bats
#!/usr/local/bin/bats @test "test Hello" { [ "Hello" = `echo 'Hello'` ] }
実行する。
$ bats A.bats ✓ test Hello 1 test, 0 failures
失敗させてみる
B.bats
#!/usr/local/bin/bats @test "test Hello" { [ "Hello" = `echo 'xxxxx'` ] }
$ bats B.bats ✗ test Hello (in test file B.bats, line 4) `[ "Hello" = `echo 'xxxxx'` ]' failed 1 test, 1 failure
テスト名のほか、ファイル名、行数、テストコードが出力された。失敗した箇所が特定できる。
テスト対象が外部ファイルのとき
ふつうはそうだろう。load
コマンドを使う。
- ./
- src/
- A.bash
- test/
- A.bats
- src/
A.bash
EchoHello () { echo 'Hello'; }
A.bats
@test "test Hello" { load ../src/A [ "Hello" = `EchoHello` ] }
ここで罠がある。以下の条件でないとload
は使えない。外部ファイルを参照するためには必須条件。
load
対象ファイルの拡張子は.bash
のみload
するときは拡張子を省略せねばならない
これが非常に不満。今まで.sh
で書いてきたのに、それらはBatsで読み込めずテストできない。
罠
load
ファイルを探せない
原因:load
するとき、ファイル名の末尾に拡張子.bash
が勝手に付け加えられるから
解決:load
対象の拡張子は必ず.bash
。かつload
するときは拡張子を必ずとる
.sh
だと読めずテストできない残念仕様。
A.bats
load A.sh
$ bats A.bats bats: /.../A.sh.bash does not exist
A.sh
を対象にしたいのに、「A.sh.bash
が無い」と怒る。そんなファイルを指定した覚えはないのに。
さては.bash
以外認めないのか? と思い、A.sh
をA.bash
にリネームするも失敗。
A.bats
load A.bash
$ bats A.bats
bats: /tmp/work/Bats.Test.20180403090444/src/C.bash.bash does not exist
.bash.bash
ってなんだよ。どうやらbatsが勝手に付け加えてしまうようだ。
呼出時に拡張子をとることで成功。
A.bats
load A
$ bats A.bats ✓ test Hello 1 test, 0 failures
つまり、以下の条件を満たさねばload
は失敗し、テスト失敗となる。
- テスト対象ファイルの拡張子は
bash
であること- (
sh
だとファイルが見つからない)
- (
load
するときは拡張子を抜いたファイル名を指定すること- (batsが勝手に
.bash
を末尾に追加するので)
- (batsが勝手に
これ、使いづらい。省略時は自動補完して探すならまだしも、.bash
限定かつ呼出時は省略せねば参照不可って……。あと.sh
も探してやってください。
sourceは使えない
load
なんて使わず、.
やsource
コマンドで解決してやろうと企むも失敗。
A.bats
path_dir_this=$(cd $(dirname $0); pwd) . "${path_dir_this}/A.sh"
$ bats A.sh
/usr/local/libexec/A.sh: そのようなファイルやディレクトリはありません
確認してみると、A.bats
の起動引数は以下のようになるらしい。
引数 | 値 |
---|---|
$0 |
/usr/local/libexec/bats-exec-test |
$1 |
(空) |
テスト対象ファイルの絶対パスが欲しいのに……。救いはない。
run
run
コマンドでコマンドのテストができる。$status
、$output
で終了コードと出力結果を参照できる。
が、環境変数PATHが通っていないとテストエラーになる。
しかもメッセージからはエラーの原因がわからない。
✗ test Hello (in test file /.../A.bats, line ...) `[ "Hello" = "$output" ]' failed
そこで、echo $output
してみる。
@test "test Hello" { run A echo $output [ "Hello" = "$output" ] [ 0 -eq $status ]
以下のメッセージが表示される。
✗ test Hello (in test file /.../A.bats, line ...) `[ "Hello" = "$output" ]' failed /usr/local/libexec/bats-exec-test: 行 58: A: コマンドが見つかりません
run A
のようにA
と指定したが、「コマンドが見つかりません」と怒られる。
フルパス指定すれば実行できた。が、普通は相対パスで指定したいもの。
load
, run
, どちらのコマンドもパス絡みで不都合がある。
構文エラー時にメッセージが表示されなかった
構文エラー: 予期しないファイル終了 (EOF) です
A.sh
EchoHello () { echo 'Hello'; }
上記のようにすべきところ、;
を忘れてしまって以下のようにした。
EchoHello () { echo 'Hello' }
これをbashで実行すると以下のエラーになる。
$ bash A.sh A.sh: 行 2: 構文エラー: 予期しないファイル終了 (EOF) です
Batsでは以下の表示になった。
$ bats A.bats ✗ test Hello 1 test, 1 failure
ファイル名、行数がない。エラーの原因不明。なにもわからない。