どらちゃんのポッケ

R・統計・技術メモなど勉強ログ置き場

PowerShellの単体テストフレームワーク 

VMwareを管理している都合上、Powershell(PowerCLI)をよく使いますが、
いままでPowerShell単体テストをやってこなかったので、調べてみました。
その中で、pesterという単体テストフレームをつかってみた。
pesterのGithubみてみたけど、手入れもされているようで、良さそう。
https://github.com/scottmuc/psget


おもに下記2つのページを参考にさせていただきました。
http://scottmuc.com/blog/development/pester-bdd-for-the-system-administrator/
http://d.hatena.ne.jp/fsugiyama/20111217/p1

Pesterのセッティング
1)Pesterのダウンロード。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

とコンソールに出力される

2)インポートとインストール
以下のコマンドを入力していく

import-module PsGet
install-module Pester
import-module Pester


3)Get-Moduleコマンドでモジュールがインストールされているかどうかの確認
Get-Moduleを入力

Script Pester {Context, Describe, In, Invoke-Pester...}
Script PsGet {Get-PsGetModuleHash, Get-PsGetModuleInfo, Install-Module, Update-Module...}

画面的には、こんな感じ。

以上で設定は終わり。

Pesterで実際にテストコードを生成する
1)テストコード生成
New-Fixture 【生成先のパス】【ファイル名】で生成

New-Fixture powershellScript sample1
Creating => powershellScript\sample1.ps1
Creating => powershellScript\sample1.Tests.ps1


とコンソールに表示され、sample1.ps1とTest.ps1が生成される。

それぞれの中身は。。。
本体

function sample1 {

}

本体には関数名だけ生成させる


Test.ps1

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
. "$here\$sut"

Describe "sample1" {

It "does something useful" {
$true.should.be($false)
}
}

テストには、いろいろある
ここからコードをいろいろ書き換えて、テストを実行する。ここでは、試しに奇数偶数を判別するコードを書いた。

本体

function sample1 ([int16] $num){
if($num % 2 -eq 0) {
return "偶数"
}else{
return "奇数"
}
}

テスト

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
. "$here\$sut"

Describe "sample1" {

It "奇数偶数のテスト" {
$result = sample1(2)
$result.should.be("偶数")
}
}

Invoke-Pesterのコマンドでテストを実行する。
注意1:Junitとかみたいに、テストコマンドそのものをF5とかで実行するものではない!!
注意2:PowerShellの実行ディレクトリをテストコードがあるディレクトリに変更しないといけない
実行ディレクトリ内にあるファイルで、ファイル名に【Test】と含まれるものを順次実行していく。

テストに通ると、緑色で、It以下が表示される

[+] 奇数偶数のテスト (136ms)

テストに失敗すると以下のようになる。

[-] 奇数偶数のテスト (220ms)
"1" 個の引数を指定して "be" を呼び出し中に例外が発生しました: "Expected: 偶数. But was: 奇数"
at line: 9 in C:\Users\michi\powershellScript\sample1.Tests.ps1

ふんふん。予測を実測がちゃんとでるのね。

結果の最後の部分には、以下のように表示される

Tests completed in 10ms
Passed: 1 Failed: 0

複数テストも大丈夫ですね。



ここで気になるのが、
Start-TranscriptとStop-TranscriptがPSNotSupportedExceptionの例外を吐いていること。

補足
Start-Transcriptメソッドはpowershellのコンソール内容を出力してくれるもの。
http://technet.microsoft.com/ja-jp/library/dd347721.aspx

ホストが対応していないってでてるけど、Start-TranscriptだけをPoweshellで動かしたら、正常に出力されたんだよな。
とりあえず、テスト動作には、影響がない模様。
権限問題なのか?んー。わからない・・・。