テストの仕方ってよくわからないんですが、PowerShellのテストフレームワークを探していたらPesterというのを見つけたので、これを使ってみます。
Pesterをインストールする
3年前の記事だけど、PowerShellの単体テストフレームワーク / どらちゃんのポッケを参考にインストール。
(*'-') >> (new-object Net.WebClient).DownloadString("http://bit.ly/GetPsGet") | iex
Downloading PsGet from https://github.com/psget/psget/raw/master/PsGet/PsGet.psm1
PsGet is installed and ready to use
USAGE:
PS> import-module PsGet
PS> install-module PsUrl
For more details:
get-help install-module
Or visit http://psget.net
(*'-') >> import-module PsGet
(*'-') >> install-module PsUrl
"C:\Users\IEUser\Documents\WindowsPowerShell\Modules" is added to the PSModulePath environment variable
Module PsUrl was successfully installed.
(*'-') >> install-module Pester
Module Pester was successfully installed.
(*'-') >> import-module Pester
これで使えるようになった。毎回モジュールを読み込むのも面倒なので、$profile
ファイルの最後にでも次の2行を足しておく。
Import-Module PsGet
Import-Module Pester
テストの準備
テストコードの作成はNew-Fixture
で。
最初の引数はカレントディレクトリを起点としたテストコードの作成場所。2番目の引数はテストコードファイルのベースネーム。同じ名前にするとややこしいね。
(*'-') >> New-Fixture chkopt chkopt
ディレクトリ: C:\Users\home\chkopt
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2015/11/03 16:06 27 chkopt.ps1
-a---- 2015/11/03 16:06 249 chkopt.Tests.ps1
(*'-') >>
バージョンが違うのか、さっきの記事の内容とは少しコードが違うので今度はWindows PowerShellでBDD / 株式会社SHIFTを参考に。
テスト対象テンプレート
function chkopt {
}
テストコードテンプレート
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
. "$here\$sut"
Describe "chkopt" {
It "does something useful" {
$true | Should Be $false
}
}
テストコードを書いてみる
オプションチェックの関数をテストしてみましょう。シェルスクリプトの引数として与えられた値が、オプションとして有効か否かを判定する関数です。
$opt_sw
にスクリプトの引数(例えばargs[0])、$opt_lst
に有効なオプションリストを配列で与えると、$ret_code
でチェックの結果を返します。
有効なオプションであればオプションリストの何番目であるかを整数で、無効なオプションであれば0を返します。
function Check-OptionSwitch($opt_sw, $opt_lst) {
$ret_code = 0
for ($loop_n = 0; $loop_n -lt $opt_lst.length; $loop_n++) {
if ($opt_sw -ceq $opt_lst[$loop_n]) {$ret_code = 1 + $loop_n}
}
return $ret_code
}
テストコードはDescribeで囲まれた中の条件を書き換えます。
-
Describeに続けてテストするモジュールの識別名"chkopt"を書きます。今回はひとつしかテストしないのでどうでもいいんですが、複数テストをするとどの部分かわからなくなるので一意な名前にしましょう。
-
Itに続けてテストの内容を書いておきます。出力結果がOKかNGかしか出ないので、実際にどんな条件でテストしているかを書いておくとわかりやすいです。
-
で、{}内が実際のテストの中身。"| Should Be"の前後(左辺と右辺)をそれぞれ書き換えます。左辺にテストする関数とそれに与える引数を、右辺に期待する結果を記述します。
今回はDescribeの前に$option_list
で設定した"-a", "-v", "-h"の三つに対して、それぞれ1, 2, 3が返されることを確認します。なお、今回の関数は大文字と小文字を区別するようにしたので、"-A"を与えたときに無効と判定し0を返すことも確認します。
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
. "$here\$sut"
$option_list = @("-a", "-v", "-h")
Describe "chkopt" {
It "1番目の-aオプションは1" {
Check-OptionSwitch "-a" $option_list | Should Be 1
}
It "2番目の-vオプションは2" {
Check-OptionSwitch "-v" $option_list | Should Be 2
}
It "3番目の-hオプションは3" {
Check-OptionSwitch "-h" $option_list | Should Be 3
}
It "オプションに存在しない-Aは0" {
Check-OptionSwitch "-A" $option_list | Should Be 0
}
It "オプションが存在しない時は0" {
Check-OptionSwitch "" $option_list | Should Be 0
}
}
テストしてみる
テスト実行はchkopt.Test.ps1またはInvoke-Pester
で。複数のテストスクリプトを一気に実行するときはInvoke-Pester
を使います。
(*'-') >> .\chkopt.Tests.ps1
Describing chkopt
[+] 1番目の-aオプションは1 46ms
[+] 2番目の-vオプションは2 52ms
[+] 3番目の-hオプションは3 40ms
[+] オプションに存在しない-Aは0 126ms
[+] オプションが存在しない時は0 231ms
(*'-') >>
無事にテストが通りました。
ちなみにテストがエラーになると、エラー部位を赤字で教えてくれます。
(*'-') >> .\chkopt.Tests.ps1
Describing chkopt
[+] 1番目の-aオプションは1 58ms
[+] 2番目の-vオプションは2 42ms
[-] 3番目の-vオプションは3 90ms
Expected: {3}
But was: {2}
at line: 14 in C:\Users\home\chkopt\chkopt.Tests.ps1
14: Check-OptionSwitch "-v" $option_list | Should Be 3
[+] オプションに存在しない-Aは0 58ms
[+] オプションが存在しない時は0 41ms
(*'-') >>
テストコードを書くときにコピペしたら3番目の条件指定を間違えちゃった。
とりあえず、一番簡単な使い方がこんなところかな。