ShellScript
Bash
CircleCI
shUnit2

CircleCIでshUnit2のテストを実施する

More than 1 year has passed since last update.

先日、「shUnit2を使おう」という以下のLTをしてきました。

http://www.slideshare.net/cottondesu/shell-02-shunit2

shUnit2を使ってシェルのテストするまでLTをしましたが、

本当はこのLTには続きあります。

動作確認する時間、スライドを作成する時間がなかったので実現

できなかったのですが、GithubとCircleCIが連携し

CircleCIでshUnit2のシェルテストを行うことです。


目的

Githubにpushし、CircleCIでshUnit2のテストを実施する


環境


  • Mac

  • shUnit2

  • Github

  • CircleCI


shUnit2のインストール

以下のURLを開く

https://code.google.com/archive/p/shunit2/

Downloadsからshunit2-2.1.6.tgzをダウンロードします。

ターミナルから以下のコマンドを実行しフォルダを作成、

ダウンロードしたtgzファイルを展開します。

$ mkdir ~/.shunit2

$ tar zxf shunit2-2.1.6.tgz -C ~/.shunit2

以下のように環境変数(bash)を設定します。

$ echo 'export SHUNIT2_HOME=$HOME/.shunit2/shunit2-2.1.6' >> ~/.bash_profile

$ . ~/.bash_profile

sampleのテストコードは.shUnit2のexamplesディレクトリに

格納されているのでそちらでテストコードの書き方を確認ください。


bashスクリプトのプロジェクト作成

テスト対象のシェルスクリプトとテストコードが必要になります。

ここではテストコードの書き方は省きます。

私の場合、シェルスクリプトがGithubにおいてあるのでこちらを使います。

https://github.com/cottondesu/shell_create_kzrb_meetup

シェルスクリプトのテスト対象ファンクション部分


create_kzrb_meetup.sh

#モード選択

select_mode() {
if [[ "$1" =~ ^[1-2] ]]; then
return
0
else
return
1
fi
}

#meetup番号入力
input_meetupnum(){
if [[ "$1" =~ ^[0-9]+$ ]]; then
return
0
else
return
1
fi
}

#フォルダ存在チェック
is_filefolder(){
if [ ! -e "$1" ]; then
return
1
else
return
0
fi
}


テストコード


test/function_test.sh

#!/bin/bash

# shellcheck source=./../../shell_create_kzrb_meetup/create_kzrb_meetup.sh
. "$(dirname "${BASH_SOURCE:-$0}")/../../shell_create_kzrb_meetup/create_kzrb_meetup.sh"

testSelectMode1(){
select_mode 1
assertEquals 0 $?
}

testSelectMode2(){
select_mode 2
assertEquals 0 $?
}

testSelectModeNg(){
select_mode 3
assertEquals 1 $?
}

testInputMeetupNum1(){
input_meetupnum 1
assertEquals 0 $?
}

testInputMeetupNum40(){
input_meetupnum 40
assertEquals 0 $?
}

testInputMeetupNumNg(){
input_meetupnum a
assertEquals 1 $?
}

testIsFile(){
is_filefolder "$0"
assertEquals 0 $?
}

testIsFileNg(){
is_filefolder "index.md"
assertEquals 1 $?
}

testIsFolder(){
is_filefolder ../test
assertEquals 0 $?
}

testIsFolderNg(){
is_filefolder test
assertEquals 1 $?
}

# shellcheck source=$HOME/.shunit2/shunit2-2.1.6/src/shunit2
. "$SHUNIT2_HOME/src/shunit2"


因みに上記のfunction_test.shをshellcheckするとnoteが2件でます。

shellcheck -xで実行すると57行目の1件のみnoteで出ます。

$HOMEを実際のパスに置き換えるとnoteが消えます。


Githubにpush

私の場合は既にGithubにシェルスクリプトが格納されているので

テストコードを追加してpushします。

$ git add test/function_test.sh

$ git commit -m "テストコードを追加"
$ git push origin master


CircleCIの設定

CircleCI

https://circleci.com/


  1. CircleCIにgithubのアカウントでログインする

  2. 左側のメニューにある[ADD PROJECT]を選択する

  3. pushしたリポジトリの「BuildProject」を選択する。

3.を行うとすぐさまbuildが実施されますが、

「NO TESTS」となります。testが実施されていませんからね。

testが実施されるようにcircle.ymlを作成する


circle.yml

machine:

environment:
SHUNIT2_HOME: ${HOME}/.shunit2/shunit2-2.1.6

dependencies:
pre:
- "[ ! -e ~/.shunit2 ] && wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/shunit2/shunit2-2.1.6.tgz && mkdir ~/.shunit2 && tar zxf shunit2-2.1.6.tgz -C ~/.shunit2 || echo 'ready'"
cache_directories:
- "~/.shunit2"

test:
override:
- bash test/function_test.sh


test:の所でpush時に実行されるテストコードを指定します。

私の場合は、test/function_test.sh となります。

作成したcircle.ymlをpushする

$ git add circle.yml

$ git commit -m "add circle yml"
$ git push origin master

pushすると、CircleCI上でshUnit2によるテストが実行されます。

ここで成功したよドヤって言いたかったんですが、私のテストコードが

悪かったせいでFAILEDになってしまいました。

ローカル環境でのテスト実施はtestフォルダに移動して

テストコードを実施していました。

$ sh function_test.sh

上の階層(shell_create_kzrb_meetup)に移動して

テストコードを実施すると、CircleCIで実施した時と同じ

FAILEDが再現できました。

$ sh test/function_test.sh

ファイル存在やフォルダ存在などパスを確認するテストコードを

作成するときは実行するカレントフォルダを意識する必要があります。

我が身を持って大変勉強になりました。

以下のようにテストコードを直します。


function_test.sh修正前

testIsFolder(){

is_filefolder ../test
assertEquals 0 $?
}

testIsFolderNg(){
is_filefolder test
assertEquals 1 $?
}



function_test.sh

testIsFolder(){

is_filefolder test
assertEquals 0 $?
}

testIsFolderNg(){
is_filefolder exsample
assertEquals 1 $?
}


として直してcommit、pushします。

$ git add test/function_test.sh

$ git commit -m "テストコードの修正"
$ git push origin master

無事、単体テストが成功しました。

本当は成功例のみを載せたほうが良いのかもしませんが

失敗例含めて少しでも役に立てば有難いです。


参考にした記事

shUnit2とCircleCIでシェルスクリプトの単体テストをしてみた