Silverlight Unit Test Runner について

前にも少し書いたんだけど、Silverlight の UnitTest を自動実行したいので少し調べてみました。

Silverlight サーバー側処理(非同期処理)の モック を作る - お だ のスペース から引用

後は、テスト結果が NUnit みたく xml ファイルで出力出来ないのかなぁ? CruiseControl.NET とも連携出来る様になるし。
一応、テストプロジェクトが出力した html(TestPage.html)を開いたらテストを実行してくれるから、
ビルド後に、TestPage.html と 〜.xap を 見える場所に配置したら運用で何とかなりそうなんだけど。。
ただ、html を開かないとテストが実行されないし、エラーが発生しても通知出来るかわからないから自動ビルドの一環には、取り入れられないかもしれないなぁ。。

正直日本語の情報は殆どなくて、読めない英語のページを漁ってると、幾つかのサイトを見つけたので紹介します。


Odin - Home
見つけた中では、ちゃんとリリースされてた TestRunner。(Ver 0.4 だけど)

  • 良い所:
    • ちゃんと動いた。
  • ダメだった所:
    • テストの実行結果が寂しい。
    • 結果がConsole に出力される。(別ファイルに保存して欲しい)
    • 実行中に ASP.NET 開発サーバーが立ちあがるんだけど、それが実行後に終了しない!(何回も実行すると、何個も立ち上がる。これでは、CI サーバーには載せれない)


ちなみに、実行結果

失敗の時成功の時


実行の仕方は、インストーラーでインストールして、%PROGRAMFILES%\DoLittle Studios\Odin\Odin.Runners.CommandLine.exe に テストしたい xap ファイルのパスを引数として渡すだけ。
Vista の場合、管理者として実行しないとエラーが発生します!

実行例:cmd.exe から

%PROGRAMFILES%\DoLittle Studios\Odin\Odin.Runners.CommandLine.exe "〜.xap"


2009 coming to an end – Welcome 2010 | Einar Ingebrigtsens Playground
これは、Odin の作者のブログなのかな?ちゃんと読んでない(英語が読めない)ので、間違ってるかも。


CodePlex - Page Not Found Command Build
これは、未だリリースされていないのでソースをリポジトリから取得して、ちょっと眺めてみました。ぱっと見た感じ、MSBuild のカスタムタスクを作成しているみたい。
が、どう使って良いのかわからず挫折。


SilverLight tests + PowerShell = Automated tests in MSBuild » Lab49 Blog
これは、PowerShell から IE を起動して Silverlight のテストページを開き、テストが終わったら結果を html に出力しようとしています。

ページのソースを引用 (このまま、コピーしてもエラーになります。'(シングルクォーテーション)と"(ダブルクォーテーションを) を正しく置き換えて下さい)

param($testURL, $outFile=”TestReport.html”, $visible=$true)
#Instanciate IE, set Visible mode (tests that interact with desktop will require $true to pass
#then navigate to the test page
$ie = new-object -com “InternetExplorer.Application” 
$ie.Visible = $visible 
$ie.Navigate($testURL)  
#poll the content until test execution is complete.
#Note: using $ie.Busy won’t work, because it does not detect that SL application is still running.
#Furthermore, the SL application is running until you close the browser, even after all the tests complete
while (!($ie.Document.body.innerHTML -match “\[ Close \]”))
{
[System.Threading.Thread]::Sleep(100)
}
#Once the execution is complete, we can check the results
#and, thanks to artist rendition by D. Finke, display some shining colors!
$failure = $ie.Document.title -match “(\d*) failures”
if($failure) {Write-Host -NoNewline -ForegroundColor “red” “Failed $matches[1]”}
else {Write-Host -NoNewline -ForegroundColor “green” “Pass   “}
#Heavy RegEx stuff to reformat the body HTML.
#The test results in the SL test framework are displayed  as a narrow column on the right with some
#error messages wrapped into context pop-up or limited in width.
$regOpt = [System.Text.RegularExpressions.RegexOptions]
[regex]::Replace($ie.Document.body.innerHTML, ‘^.*<DIV style=”RIGHT.*?</DIV></DIV>’, “”, $regOpt::Singleline) -ireplace “width: 324px”, “” -ireplace ‘<SPAN title=\”(.*?)\”.*?\(Mouse over for assert trace\)</SPAN>’, ‘$1′ -ireplace ‘</DIV>\w*$’, “” > “$outFile”
#return error code in case of failure so that MSBuild and other tools can detect it. 
Write-Host $testUrl
$ie.Quit()
if ($failure) { exit 1 }

何をしているかというと、PowerShell で IE を立ち上げ、テストページ の URL を開く。
んで、テストが終わるまで待つ。(while 〜 のところ)
テストが終わったら、正規表現で テスト結果を抜き出し、別ファイル($outFile)に書き出す。
正規表現は、ちゃんと見てないので何を抜き出してるかは各自判断して下さい。
最後に IE を終了してテストが失敗してたら、 1 を返す。


これを試してみたんだけど、一部間違いがありました。(TestFramework のバージョンなのかも)
while ループの条件で "[ Close ]" が見つかるまでループするってなってるんだけど、これが、"(Close)" にしないと、条件に引っ掛からない。
これ多分、
の一番下の部分のTest Run Complete (Close) ってのが出力されるまで待つって処理なんだと思う。
なので、[ Close ] だと、マッチせずに、無限ループに陥った。
でwhile ループの条件を

while (!($ie.Document.body.innerHTML -match '\(Close\)'))

にしたら、なんかテストが全部終わる前に結果ファイルを出力してしまった。これは原因不明。(もう少し調べる必要あり)
とりあえず、条件をもう少し前から指定したら 最後まで実行してくれた。

while (!($ie.Document.body.innerHTML -match 'href=\"javascript:void\(0\)\">\(Close\)'))


Unit testing Silverlight Tutorial SilverUnit Test -
ここは、どうも別の UnitTest の Framework みたい。ちゃんと見てない。


で結局 PowerShell でやってみようかなと思ってます。ただ、実行結果が html になるので、他の NUnit の結果と一緒に出来ないのが残念。(テストの数とか、成功・失敗の数とか)
これを、Hudson に載せようと試行錯誤中。。NUnit と同じフォーマットで結果を xml で保存出来たらいいんだけど。。
今のところ、Hudson の プロジェクトの説明を記入ってとこに、iframe タグでぶち込んどこうと思います。