MsBuildって便利ですね しみじみ
自動化は男のロマン。
と言うことで、WindowsPhoneプロジェクトの
-ビルド
-テスト
-結果の回収
を自動で行おうと思います。ゆくゆくは、Jenkinsを利用したCIへと繋がります。
今回は、http://blogs.msdn.com/b/francischeung/archive/2012/01/03/running-windows-phone-unit-tests-via-msbuild.aspx
の内容ホボそのまま。
一連の自動化の流としては
1.ビルド実行
2.エミュレーターへのインストール
3.テスト実行
4.テスト結果を エミュレーターの分散ストレージに保存
5.テスト結果をローカルにコピー
1.プロジェクトを作る
作りましょう2.テストプロジェクトを作る
以前の投稿 http://numa08.blogspot.jp/2012/09/windowsphonerx_19.html や、@okazuki さんのhttp://d.hatena.ne.jp/okazuki/20110911/1315724390
あたりを参考にテストプロジェクトを作りましょう。
3.ログをファイルに出力する
ファイルと言っても、エミュレーター上の分散ストレージです。テストプロジェクトに次のコードを追加します。
その上で、テストプロジェクトのMainPage.xaml.csを次のように変更します。
4.MsBuildタスクのプロジェクトを作る
ソリューションに新しい VisualC# クラスライブラリ を作成します。参照に、
Microsoft.Build
Microsoft.Build.Engine
Microsoft.Build.Framework
Microsoft.Build.Task.v4.0
Microsoft.Build.Utilities.v4.0
を追加。次に、
"C:\Program Files (x86)\Common Files\microsoft shared\Phone Tools\CoreCon\10.0\Bin\Microsoft.Smartdevice.Connectivity.dll"
を参照に追加します。
5.タスクを書く。
MsBuildって本当に強力だなぁとしみじみ。ぶっちゃけ、次のコードのコピペで動きますけど、もっともっとカスタマイズすると楽しいと思います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using Microsoft.Build.Utilities; | |
using Microsoft.SmartDevice.Connectivity; | |
using System.Threading; | |
using System.Globalization; | |
using System.IO; | |
using Microsoft.Build.Framework; | |
namespace MyMsBuildTask | |
{ | |
public class RunWP7UnitTestsInEmulator:Task | |
{ | |
private int defaultNumberOfMiliSecondsToProcess = 50000; | |
[Required] | |
public string PathToUnitTestXapFile { get; set; } | |
[Required] | |
public string ProductGuid { get; set; } | |
public int NumberOfMilliSecondsToProcess { get; set; } | |
public override bool Execute() | |
{ | |
if (NumberOfMilliSecondsToProcess == 0) | |
{ | |
Log.LogMessage(string.Format("Using default processing time: {0}", defaultNumberOfMiliSecondsToProcess)); | |
NumberOfMilliSecondsToProcess = defaultNumberOfMiliSecondsToProcess; | |
} | |
Log.LogMessage(string.Format("NumberOfMilliSecondsToProcess: {0}", NumberOfMilliSecondsToProcess)); | |
Log.LogMessage("Running tests in XAP: " + PathToUnitTestXapFile); | |
var productGuid = new Guid(ProductGuid); | |
var emulator = GetWP7Emulator(); | |
Log.LogMessage("Connecting to Emulator."); | |
emulator.Connect(); | |
Log.LogMessage("After call to Connect()."); | |
//Deploy application | |
if (emulator.IsApplicationInstalled(productGuid)) | |
{ | |
emulator.GetApplication(productGuid).Uninstall(); | |
} | |
emulator.InstallApplication(productGuid, productGuid, "NormalApp", null, PathToUnitTestXapFile); | |
//Run application | |
var application = emulator.GetApplication(productGuid); | |
application.Launch(); | |
Thread.Sleep(NumberOfMilliSecondsToProcess); | |
//Get Results from Isolated Store on device | |
var isostorefile = application.GetIsolatedStore(); | |
var localTestResultFileName = "EmulatorTestResults-" + productGuid + ".txt"; | |
isostorefile.ReceiveFile(@"\TestResults\testresults.txt", localTestResultFileName, true); | |
var testResults = File.ReadAllText(localTestResultFileName); | |
if (testResults.Contains("Exception:")) | |
{ | |
Log.LogError("Failing test found. Look for exception in: " + localTestResultFileName); | |
return false; | |
} | |
Log.LogMessage("All tests passed."); | |
emulator.Disconnect(); | |
return true; | |
} | |
private Device GetWP7Emulator() | |
{ | |
var manager = new DatastoreManager(CultureInfo.CurrentUICulture.LCID); | |
var wp7Platform = manager.GetPlatforms().Single(platform => platform.Name == "Windows Phone 7"); | |
return wp7Platform.GetDevices().Single(device => device.Name == "Windows Phone Emulator(JA)"); | |
} | |
} | |
} |
6.MsBuildファイルを書く
こちらは、テストプロジェクトのUUIDやファイルパスなどを指定する必要があります。さっき作ったprojファイルから見た相対パスらしいので、それに合わせてxapファイルのパスを適切に設定します。
ProductGuidはテストプロジェクトの WMAppManifest.xml のAppタグOriductIDの値を使います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8" ?> | |
<Project DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" > | |
<UsingTask TaskName="MyMsBuildTask.RunWP7UnitTestsInEmulator" | |
AssemblyFile="MyMsBuildTask.dll"/> | |
<PropertyGroup> | |
<SourceFilesPath>$(MSBuildProjectDirectory)</SourceFilesPath> | |
</PropertyGroup> | |
<ItemGroup> | |
<SolutionItemsToBuild Include="$(SourceFilesPath)\**\*.sln" /> | |
</ItemGroup> | |
<Target Name="Build"> | |
<MSBuild Projects="%(SolutionItemsToBuild.Identity)" Targets="Build"/> | |
</Target> | |
<Target Name="Test" DependsOnTargets="Build"> | |
<RunWP7UnitTestsInEmulator NumberOfMilliSecondsToProcess="50000" | |
PathToUnitTestXapFile="$(SourceFilesPath)\(your test project).xap" | |
ProductGuid="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" /> | |
</Target> | |
</Project> |
7.実行する
エミュレーターを立ち上げた状態で MsBuild msbuild.proj としてやれば、自動的にプロジェクトのビルドと、テストの実行が走ります。
最後に、EmulatorTestResult-$(GUID)-.txtが吐き出されていれば成功。
何が凄いって、テストに失敗するとテストに失敗すると、例外を検知してMsBuildが失敗を返すところ。
これは便利です。Jenkinsの場合、ビルドの成功失敗は取れてましたけど、テストの成功失敗は別で管理してました。
あー、でもこのテストの失敗は無視ー とかそういう状態も発生するわけか。まあ、その辺はタスクのカスタムでなんとかなるんだと思います。
思いますよ。そのうちやります。
0 件のコメント:
コメントを投稿