0.前置き
この記事はPowerShell Advent Calender 2012の17日目のエントリーです。
前日は@Chukiさんの「Active Directoryの管理なら 7/R2以降を使いましょう^^」でした。
今回は、PowerShellのユニットテストの内容を書こうと意気込んでいましたがなんと@fsugiyamaさんが2011年のAdventCalenderで書いていらっしゃいました。今回はせっかくなので導入編は省いて、マニュアルっぽくまとめてみたいと思います。
0-1.Pesterの紹介
BDDスタイルテスティングフレームワークです。
・本家のサイトはこちらのgithubで。
・日本語だと@fsugiyamaさんのPester – BDD style testing framework for PowerShell。
0-2.コンテンツ
マニュアルになるように以下の順序に沿って整理していきます。
記載の分類は、「JUnit実践入門」、記載内容は、Pesterの解説ページなどを参考にしています。
- 1. テストの準備
- 2. アサーション
- 3. テストランナー
- 4. テストのコンテキスト
- 5. モック
- 6. CIとの統合
1. テストの準備
Get-Hogeというコードの作成と、これに対するテストコードの作成を行いましょう。
まずはPesterの機能を用いてスケルトンと呼ばれるテンプレートを作成します。
[sourcecode language=”powershell”]
PS D:\xxx> New-Fixture scripts Get-Hoge
Creating => scripts\Get-Hoge.ps1
Creating => scripts\Get-Hoge.Tests.ps1
PS D:\xxx>
[/sourcecode]
Get-Hoge.ps1が本体のコードを格納するファイル、Get-Hoge.Tests.ps1がテストコードを格納するファイルになります。
2. アサーション
続いて、アサーション(検証方法)を整理していきます。
Pesterでは、「Should」オブジェクトを利用して検証を行います。「Should」のメンバーには以下のものがあります。
多くが内部的にはPowerShellの標準機能をそのまま利用しています。
Be
2つのオブジェクトを比較します。
[sourcecode language=”powershell”]
$actual="こんにちは"
$actual.should.be("こんにちは") // 成功する
[/sourcecode]
Hava_Count_Of
IEnumerable型オブジェクトの件数を検証します。
[sourcecode language=”powershell”]
@(1,2,3,4).should.have_count_of(5) # 失敗する
[/sourcecode]
Exist
PSドライブ内に対象が存在するかどうかチェックします。
ファイル・フォルダーの存在チェックや、レジストリー値の存在チェックなどなんでもOK。
Test-Pathと同等の検証機能です。
[sourcecode language=”powershell”]
"C:\hogehoge\fuga".should.exist()
[/sourcecode]
Match
正規表現を利用して2つのオブジェクトを比較。
PowerShellの正規表現と同等の検証機能。
[sourcecode language=”powershell”]
"192.168.1.1".should.match("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") # 成功
[/sourcecode]
Be_Like
ワイルドカードを利用して2つのオブジェクトを比較。
[sourcecode language=”powershell”]
"PowerShell".should.be_like("P*S*") # 成功
[/sourcecode]
3. テストランナー
テストを実行するときは、Invoke-Pesterを利用します。
このコマンドを利用すれば、指定したフォルダー以下にあるテスト用のファイルを再帰的に探し実行してくれます。
オプションを指定することによって、テスト結果をNUnitのレポート形式(?)にて出力できます。
[sourcecode language=”powershell”]
Invoke-Pester -OutputXml "TestResults.xml"
[/sourcecode]
実行結果は以下のように表示されます。
4. テストのコンテキスト
テストケースが複数になった場合は、グループ化して可読性をあげる必要があります。
そのためにPesterでは、Describe、Context、Itを利用します。
Itが1テストケースに相当します。ContextがItをまとめたもの。DescribeがContextをまとめたものです。
[sourcecode language=”powershell”]
Describe "Exec-Calc" {
Context "例外処理の確認"{
It "引数がnullかチェックする"{
#…
}
It "引数が数値かチェックする"{
#…
}
}
Context "本体処理の確認"{
It "加算処理を実行する"{
#…
}
It "減算処理を実行する"{
#…
}
It "除算処理を実行する"{
#…
}
It "乗算処理を実行する"{
#…
}
}
}
[/sourcecode]
テストの実行結果はこのようにグループ化されて表示されます。
5. モック
PowerShellは利用されるシチュエーション上、外部モジュールとのやりとりが気持ち多くなる気がします。
ユニットテストを行う場合、その外部モジュールの挙動をシミュレーションするモックが重要になります。
モックの作成方法と、モックの検証方法は以下の通りです。
[sourcecode language=”powershell”]
#モックを作成
Mock Get-Hoge { return 2 }
#モックを作成(パラメータによってモックを起動するかどうか指定する)
Mock Get-Hoge {return 7} -parameterFilter{$val -eq 10}
#モックの検証(-verifiablez属性を付与したモックが利用されたかどうか)
Mock Get-Hoge -verifiable {return 7}
Assert-VerifiableMocks
#モックの検証(モックが指定回数呼ばれたかどうか)
Assert-MockCalled Get-Hoge-Times 10
[/sourcecode]
6. CIとの統合
PesterはさまざまなCIツールと統合することができます。
PowerShellのコマンドで走らせてもよいのですが、batがあります。
[sourcecode language=”bash”]
./pester.bat
[/sourcecode]
もちろんNunitと同じ形式でテスト結果を出力できます。(「3.テストランナー」参照)
7.最後に
PowerShellのコードもユニットテストをしようということで、Pesterを紹介しました。
なるべく全機能を紹介するようしました。
これだけあれば、あとはテストコードを書き始めるだけ!
明日は、@ichiohtaさんです!お願いしますー。
コメント