4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

私的shellspec Tips

4
Last updated at Posted at 2020-03-17

概要

最近開発したシェルスクリプトのテストツールとしてshellspecを活用している。
シェルスクリプトは、

  • 処理が比較的高速
    単体で並列化も可能
  • 簡単
    コマンド並べるだけ
  • 追加パッケージ不要

というメリットがあり、特にインフラ界隈ではしょっちゅう使用するものの、モジュール化しにくいので見通しが悪く、バグを作り込みやすい。
そして記述済みの部分に場当たり的に修正や機能追加を行ってブラックボックス化してしまうこともしばしば。

テストツールを使って、細かい処理毎に関数を設けてテストを繰り返すことで、品質の向上が期待できる。
また、リグレッションテストを容易にすることでリファクタリングのハードルを下げ、ブラックボックス化を抑止できる。

いざ使ってみたところ、テストツールに対する私の理解があまりなかったこともあって、テストの作成にかなり時間がかかってしまった。

ここでは、テストで確認したい内容の実現方法について自分用にまとめる。

When句で実施した処理の結果をコマンドで確認する。

When call/runで関数/コマンドを実行したあと、別のコマンドで結果を確認する場合。例えば、サブプロセスを立ち上げるシェルスクリプトを実行して、プロセスが存在しているか調べる。

追記:作者の方からコメントいただいたので記載見直ししました。

Describe "コマンド結果確認"
  check_subprocess(){
    [[ $(pgrep -f subprocess.sh | wc -l) -gt 0 ]] && echo OK
  }

  It "サブプロセス起動"
    When run ./start_subprocess.sh
    The result of "check_subprocess()" should eq OK
 End
End

関数以外の処理をスキップさせる

Include句でシェルスクリプトを読み込むと、関数内に記述していない処理は実行されてしまう。

test.sh
# !/bin/bash

function hoge(){
    echo "hoge"
}

hoge
echo "fuga" >&2
test_spec.sh
Describe "test"
  Describe "test"
    Include ./test.sh

    It "hoge()"
      When call hoge
      The output should eq "hoge"
    End
  End
End

以下の実行結果を見ると、テストそのものはOKとなっており問題はないのだが、"fuga"が出力されてしまっていることがわかる。

Running: /bin/bash [bash 5.0.3(1)-release]
fuga
Unexpected output to the stderr at line 2-4 in 'spec/hello_spec.sh'
.

Finished in 0.26 seconds (user 0.26 seconds, sys 0.05 seconds)
1 example, 0 failures

An unexpected error occurred or output to the stderr. [0] [0] [102]
Fatal error occurred, terminated with exit status 102.

${__SOURCED__:+return}を関数外処理の始まりに記載する。
shellspec実行時はここで処理が打ち切られるので関数外処理が実行されずにすむ。

test.sh
# !/bin/bash

function hoge(){
    echo "hoge"
}


# shellspecテスト時は以下の処理は実行しない。
${__SOURCED__:+return}

hoge
echo "fuga" >&2

動作するシェルを指定する。

.shellspecファイルに以下を追記する。

.shellspec
--shell bash

パターンをまとめて列挙する

test_spec.sh
Describe 'DHCPCDは起動していて、wpa_supplicantは停止していることを確認する。'
  Parameters
    "#1" "dhcpcd" 0
    "#2" "wpa_supplicant" 3
  End

  Example "example $1"
    When run sudo systemctl status $2
    The status should eq $3
  End
End

標準出力が指定した行を含むかチェックする。

test_spec.sh
Describe "IP addr check"
    grep_eth0(){
        # $1に標準出力、$2にエラー出力、$3に返り値が入る。
        echo "$1" | grep "eth0" | awk '{if($1=="inet")print $2}'
    }
    It "eth0に規定のIPアドレスが設定されているか確認する。"
         When run ip a
         The result of "grep_eth0()" should eq "192.168.3.142/24"
    End
  End

以下、おいおい追記していく

4
2
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?