Workflow Foundation 4into Test Driven Develop                     Ahf(小尾 智之)
自己紹介VB と SQL Server がメインの何でも屋インディー団体を含むプロレス全般と クマ(クマー含む)やもふもふしたもの好き 黙って宇宙戦艦ヤマト2199 は見ておけWorkflow Foundation ソムリエが目標@I...
おさらいWorkflow Foundation とは
おさらい:WF の特徴・概念アクティビティと呼ばれる要素の集合振舞い・手順をモデルとして保存・実行 XML (WF3.x は xoml、WF4 は xaml)で  保存される長期間における実行をサポートしている 永続化、ブックマーク、...
おさらい:開発環境についてExpress ではそのままだと無理  デザインコンポーネント拡張が必要な為  エディタを自前で用意すれば可能WF 3.5  Visual Studio 2005    + ExtensionS for Wi...
おさらい:WF3.5 と 43.5 と 4 はクラス構成も 変更され全くの別物  基底クラスから全て異なる3.5 で実装されたアク ティビティを4 環境で 利用する特殊措置を提供  Interop アクティビティ  CodePrex ...
おさらい:WF4 での主な改善点WF 3.x よりもパフォーマンス向上 全面的に向上しすぎ 今まではなんだったんだ 参考:MSDN:Windows Workflow Foudation 4 のパフォーマンスhttp://msdn.micr...
WF でユニットテスト
WF の単体テスト Visual Studio で利用する単体テスト  プロジェクトでは WF の単体テストを  対象にしていない テストプロジェクトから参照設定を行うと怒られる Visual Studio 11 においても同様     ...
WF 固有の問題点アクティビティを   WF ランタイム機実行する方法が複        能   数       としての永続化入力待機等に用い           ロジックがあると   る            は限らないブックマーク機能
アクティビティの実行  WFアクティビティの実行方法は3通り                       最もシンプルな実行方法。WorkflowInvoker                       ブックマークが利用できない    ...
WF による永続化標準機能として SQL Server による 永続化をサポートカスタマイズによる SQL Server 以外の DB やテキストファイル等へ永続化も可能永続化機能はワークフローの内容と 直接的な関係が薄い待ち状態の際に...
ブックマーク反応が戻されるまでワークフローの実行を 一時停止し待機状態にするための仕組み 状態遷移型ワークフロー等でよく利用バックグランドでワークフローを 起動させておき、フォアグランド側の アプリから通信を行わせる形にて利用する
ロジックのないアクティビティワークフロー = アクティビティ であるので既存アクティビティを ワークフロー上に設置しただけのものも アクティビティとなるコードが存在しないアクティビティを 作ることができるVisual Studio 等でビ...
WF で TDDNUnit や MSTest、xUnit など多くの テストフレームワークがあるので利用アクティビティやワークフローの 実行ロジックが毎回必要で結構な量に  WF ランタイムを通した挙動を   テストする必要がある  ラ...
Microsoft.Activities.UnitTestingCodePlex 上で公開されている WF 用 ユニットテストライブラリ作者は Microsoft の Ron Jacobs 氏(http://blogs.msdn.com/b...
TDDの流れ   仕様の作成    テストの作成         テスト         コーディング          リファクタリング繰り返し行う
TDDの流れアクティビティの開                仕様の作成                 テストの作成発                 テスト                   コーディング                 ...
余談:VWD2010 の設定 Visual Web Developer 2010 で Nunit を  利用する場合は少し設定を行っておくと楽に 1. [ツール]-[外部ツール]にて NUnit を登録 2. [ツール]-[カスタマイズ]にて...
TDD による WF 開発
テストシナリオ渡された文字列の文字数をカウント するアクティビティの作成ワークフローに変数または引数を2つInParam1:入力文字列用の引数OutParam1:文字数のカウント結果
プロジェクトの作成               アクティビティライブラリと               して新規プロジェクト作成VWD の場合はクラスライブラリにて作成
テスト用プロジェクトの追加                        作成単体テストプロジェクトでは               クラスライブラリとして作成すWF の単体テストを行えない                    る      ...
NuGet でパッケージの追加      Microsoft.Activities.UnitTesting を NuGet にて追加するPM>Install-Package Microsoft.Activities.UnitTesting Pr...
テストの作成Imports Nunit.FrameworkPublic Class UnitTest1  <Test()>  Public Sub TestMethod1()  End SubEnd Class                 ...
テストの実行ビルド後に一度テストを実行問題なく正常終了する事を確認
テストの作成まずは要件を満たすテストを作成するその際ビルドを通すために、アクティビティの定義は同時に作成する  Imports System.Activities  Public Class ActivityT    Inherits Code...
ヘルパークラス          テスト用ヘルパークラスでは          NUnit 等と同様のメソッドや          プロパティが定義されている          AssertOutArgument          プロパティな...
テスト用ロジックの記載<Test()>Public Sub TestMethod1()  Const ORIGINAL_WORD = "Sample Word"                 想定される結果  Const RESULTVALU...
テスト失敗を確認ビルド後テストを実行し、テストが予定通り「失敗」する事を確認する                  ここからがスタート
コーディングテストを通過できるようアクティビティのコーディングを行うImports System.ActivitiesPublic Class ActivityT  Inherits CodeActivity  Public Property ...
テストとトラッキングコーディング後にテストを実行し、テストに通過する事を確認Finally                           Tracking.Trace を行う事で   testInvoker.Tracking.Trace(...
リファクタリング                                                               サロゲートペア文字での<TestCase("Sample Word", 11)>           ...
<TestMethod()>                                 MSTestの場合はTestCase属性 Public Sub TestMethod1()    TestInPrivate("Sample Stri...
Imports System.ActivitiesPublic Class ActivityT  Inherits System.Activities.CodeActivity  Public Property InParam1 As InAr...
ブックマークのテスト<Test()>                                                    WorkflowApplicationTest をPublic Sub TestBookmarkWork...
永続化のテスト  永続化テスト用ヘルパークラス   MemoryStore が用意されている    Microsoft.Activities.UnitTesting.Persistance.MemoryStore  現時点では Workf...
この作業の繰り返しにてアクティビティの実装を行う WFにおける もう1つの 実装パターン          Xamlのみで作成する          純粋なアクティビティ
Xaml のみで作成するアクティビティのサンプル
<Activity mc:Ignorable="sap" x:Class="Sequence1" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc=...
Visual Studio 上では xaml ファイルでのワー              クフローもクラスとして認識するExpress ではクラスとして認識しない
XamlInjector での呼出<TestMethod()> Public Sub TestMethodFromXaml()    Const ORIGINAL_WORD = "Sample Word"    Const RESULTVALU...
XamlInjector での呼出<TestMethod()> Public Sub TestMethodFromXaml()    Const ORIGINAL_WORD = "Sample Word"                  アク...
ワークフローサービスのテストテスト用サービスホスト• テスト方法はWCFクライアントでのアクセスと同様の  手順• 実際にサービスとして起動できる必要がある• Express の場合は Web 参照にてワークフローサービス  の  情報を取得す...
テスト対象の ワークフローサービス渡された文字列の文字数をカウントし返却するシンプルなサービス
<"Sample Word", 11)>                      モックを利用したテストのサンプル<TestCase("𠮟 る", 2)>Public Sub TestServiceUseMock(ByVal orgWord ...
<"Sample Word", 11)>                      モックを利用したテストのサンプル<TestCase("𠮟 る", 2)>Public Sub TestServiceUseMock(ByVal orgWord ...
まとめユニットテスト用ライブラリを利用する事で、 通常とほぼ同様に WF も TDD を行えますTDD で開発すると安心に繋がります特殊な要素が色々ありますが WF を 使ってみてください……
ご清聴ありがとうございました
Upcoming SlideShare
Loading in...5
×

CLRH_120414_WFTDD

576

Published on

2012/04/14 CLR/H #69 にて利用したスライド

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
576
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

CLRH_120414_WFTDD

  1. 1. Workflow Foundation 4into Test Driven Develop Ahf(小尾 智之)
  2. 2. 自己紹介VB と SQL Server がメインの何でも屋インディー団体を含むプロレス全般と クマ(クマー含む)やもふもふしたもの好き 黙って宇宙戦艦ヤマト2199 は見ておけWorkflow Foundation ソムリエが目標@IT エンジニアライフで色々書いてます
  3. 3. おさらいWorkflow Foundation とは
  4. 4. おさらい:WF の特徴・概念アクティビティと呼ばれる要素の集合振舞い・手順をモデルとして保存・実行 XML (WF3.x は xoml、WF4 は xaml)で 保存される長期間における実行をサポートしている 永続化、ブックマーク、アンロード 標準で SQL Server を容易に利用できるデザイナ上でモデル作成する方法とロジッ ク上で全てを行う方法があるGUI / CUI どちらも対応可能
  5. 5. おさらい:開発環境についてExpress ではそのままだと無理  デザインコンポーネント拡張が必要な為  エディタを自前で用意すれば可能WF 3.5  Visual Studio 2005 + ExtensionS for Windows WF  Visual Studio 2008 Standard 以降WF 4  Visual Studio 2010 Professional 以降
  6. 6. おさらい:WF3.5 と 43.5 と 4 はクラス構成も 変更され全くの別物  基底クラスから全て異なる3.5 で実装されたアク ティビティを4 環境で 利用する特殊措置を提供  Interop アクティビティ  CodePrex で移行キットを 提供…  基本は作り直し  WF 3.x を利用してないのなら 気にしないのが幸せです
  7. 7. おさらい:WF4 での主な改善点WF 3.x よりもパフォーマンス向上 全面的に向上しすぎ 今まではなんだったんだ 参考:MSDN:Windows Workflow Foudation 4 のパフォーマンスhttp://msdn.microsoft.com/ja-jp/library/gg281645.aspx
  8. 8. WF でユニットテスト
  9. 9. WF の単体テスト Visual Studio で利用する単体テスト プロジェクトでは WF の単体テストを 対象にしていない テストプロジェクトから参照設定を行うと怒られる Visual Studio 11 においても同様 クラスライブラリ プロジェクトを 利用する方法で回避
  10. 10. WF 固有の問題点アクティビティを WF ランタイム機実行する方法が複 能 数 としての永続化入力待機等に用い ロジックがあると る は限らないブックマーク機能
  11. 11. アクティビティの実行 WFアクティビティの実行方法は3通り  最もシンプルな実行方法。WorkflowInvoker  ブックマークが利用できない  ワークフロー上のイベントWorkflowApplication トラップなどが行える  WorkflowApplication + WebWorkflowServiceHost サービスとして公開 実際には IIS でのホスティングも関係
  12. 12. WF による永続化標準機能として SQL Server による 永続化をサポートカスタマイズによる SQL Server 以外の DB やテキストファイル等へ永続化も可能永続化機能はワークフローの内容と 直接的な関係が薄い待ち状態の際に永続化する制御は ワークフロー個別に記載するのではなく WF ランタイム側にて制御
  13. 13. ブックマーク反応が戻されるまでワークフローの実行を 一時停止し待機状態にするための仕組み 状態遷移型ワークフロー等でよく利用バックグランドでワークフローを 起動させておき、フォアグランド側の アプリから通信を行わせる形にて利用する
  14. 14. ロジックのないアクティビティワークフロー = アクティビティ であるので既存アクティビティを ワークフロー上に設置しただけのものも アクティビティとなるコードが存在しないアクティビティを 作ることができるVisual Studio 等でビルドすれば 通常のクラスとして利用できる
  15. 15. WF で TDDNUnit や MSTest、xUnit など多くの テストフレームワークがあるので利用アクティビティやワークフローの 実行ロジックが毎回必要で結構な量に  WF ランタイムを通した挙動を テストする必要がある  ライブラリ化で対応は可能サービスのテストも必要  セルフホストのコードを用意するか  IIS や IIS Express を利用するか
  16. 16. Microsoft.Activities.UnitTestingCodePlex 上で公開されている WF 用 ユニットテストライブラリ作者は Microsoft の Ron Jacobs 氏(http://blogs.msdn.com/b/rjacobs/) AppFabric 開発チームのシニア プログラムマネージャらしい利用する事で簡易に WF における ユニットテストが行えるようになる
  17. 17. TDDの流れ 仕様の作成 テストの作成 テスト コーディング リファクタリング繰り返し行う
  18. 18. TDDの流れアクティビティの開 仕様の作成 テストの作成発 テスト コーディング リファクタリング ワークフローの開発 ワークフローの開発 アクティビティ = ワークフロー
  19. 19. 余談:VWD2010 の設定 Visual Web Developer 2010 で Nunit を 利用する場合は少し設定を行っておくと楽に 1. [ツール]-[外部ツール]にて NUnit を登録 2. [ツール]-[カスタマイズ]にてプロジェクトの 右クリックメニューに NUnit を登録 直接ソリューションエクスプローラ上から プロジェクト指定した形で NUnit が起動できる
  20. 20. TDD による WF 開発
  21. 21. テストシナリオ渡された文字列の文字数をカウント するアクティビティの作成ワークフローに変数または引数を2つInParam1:入力文字列用の引数OutParam1:文字数のカウント結果
  22. 22. プロジェクトの作成 アクティビティライブラリと して新規プロジェクト作成VWD の場合はクラスライブラリにて作成
  23. 23. テスト用プロジェクトの追加 作成単体テストプロジェクトでは クラスライブラリとして作成すWF の単体テストを行えない る 参照の追加アクティビティライブラリへの MSTest または NUnit 等への参 参照を追加 照を追加 MSTest を利用する場合は Microsoft.VisualStudio.QualityTools.UnitTestFramework への参照を追加する(参照設定ダイアログで検索すると表示される) Nunit を利用する場合は Nunit.framework への参照を追加する
  24. 24. NuGet でパッケージの追加 Microsoft.Activities.UnitTesting を NuGet にて追加するPM>Install-Package Microsoft.Activities.UnitTesting Professional 以上の VS か VWD の場合は NuGet にて それ以外の Express な場合は CodePlex よりダウンロードして参照を追加
  25. 25. テストの作成Imports Nunit.FrameworkPublic Class UnitTest1 <Test()> Public Sub TestMethod1() End SubEnd Class NUnitImports Microsoft.VisualStudio.TestTools.UnitTesting<TestClass()>Public Class UnitTest1 <TestMethod()> Public Sub TestMethod1() End SubEnd Class MSTest
  26. 26. テストの実行ビルド後に一度テストを実行問題なく正常終了する事を確認
  27. 27. テストの作成まずは要件を満たすテストを作成するその際ビルドを通すために、アクティビティの定義は同時に作成する Imports System.Activities Public Class ActivityT Inherits CodeActivity Public Property InParam1 As InArgument(Of String) Public Property OutParam1 As OutArgument(Of Integer)Integer) Protected Overrides Sub Execute(context As CodeActivityContext) End Sub End Class
  28. 28. ヘルパークラス テスト用ヘルパークラスでは NUnit 等と同様のメソッドや プロパティが定義されている AssertOutArgument プロパティなど WF 特有の プロパティが追加された形 何らかのテストフレームワークを 利用したことがあれば特に悩む ことはないと思われる
  29. 29. テスト用ロジックの記載<Test()>Public Sub TestMethod1() Const ORIGINAL_WORD = "Sample Word" 想定される結果 Const RESULTVALUE = 11 テストするアクティビティの生成 Dim testActivity As New TDDSampleLib.ActivityT 実行用 WorkflowInvoker の生成 Dim testInvoker As WorkflowInvokerTest = Nothing Try アクティビティへパラメータを設定 Dim inArgs As New Dictionary(Of String, String) inArgs.Add("InParam1", ORIGINAL_WORD) 実行用 WorkflowInvoker の生成 testInvoker = New WorkflowInvokerTest(testActivity) 実行 testInvoker.TestActivity(inArgs) ワークフローの実行 結果の確認 testInvoker.AssertOutArgument.AreEqual("OutParam1", RESULTVALUE) Finally testInvoker.Tracking.Trace() End TryEnd Sub
  30. 30. テスト失敗を確認ビルド後テストを実行し、テストが予定通り「失敗」する事を確認する ここからがスタート
  31. 31. コーディングテストを通過できるようアクティビティのコーディングを行うImports System.ActivitiesPublic Class ActivityT Inherits CodeActivity Public Property InParam1 As InArgument(Of String) Public Property OutParam1 As OutArgument(Of Integer) Protected Overrides Sub Execute(context As CodeActivityContext) Dim inString = context.GetValue(Me.InParam1) context.SetValue(Me.OutParam1, inString.Length) End SubEnd Class規則上は「テストを通過するように単純に」処理を書くよう言われるがあまり正直にやりすぎるのも微妙なところ・・・
  32. 32. テストとトラッキングコーディング後にテストを実行し、テストに通過する事を確認Finally Tracking.Trace を行う事で testInvoker.Tracking.Trace() アクティビティのトラッキング情報がEnd Try 出力される
  33. 33. リファクタリング サロゲートペア文字での<TestCase("Sample Word", 11)> テストを追加<TestCase("𠮟 る", 2)>Public Sub TestMethod2(ByVal orgWord As String, ByVal result As Integer) テストケースの追加 テストするアクティビティの生成 Dim testActivity As New TDDSampleLib.ActivityT 実行用 WorkflowInvoker の生成 Dim testInvoker As WorkflowInvokerTest = Nothing Try アクティビティへプロパティを設定 testActivity.InParam1 = orgWord 実行用 WorkflowInvoker の生成 testInvoker = New WorkflowInvokerTest(testActivity) 実行 testInvoker.TestActivity() 結果の確認 testInvoker.AssertOutArgument.AreEqual("OutParam1", result) Finally testInvoker.Tracking.Trace() End Try テストは失敗するのでEnd Sub コードを修正する
  34. 34. <TestMethod()> MSTestの場合はTestCase属性 Public Sub TestMethod1() TestInPrivate("Sample String", 13) (ROWテスト)が利用できない TestInPrivate("𠮟 る", 2) End Sub Private Sub TestInPrivate(ByVal orgWord As String, ByVal result As Integer) テストするアクティビティの生成 Dim testActivity As New TDDSampleLib.ActivityT 実行用 WorkflowInvoker の生成 Dim testInvoker As WorkflowInvokerTest = Nothing Try アクティビティへプロパティを設定 testActivity.InParam1 = orgWord 実行用 WorkflowInvoker の生成 testInvoker = New WorkflowInvokerTest(testActivity) 実行 testInvoker.TestActivity() 結果の確認 testInvoker.AssertOutArgument.AreEqual("OutParam1", result) Finally testInvoker.Tracking.Trace() End Try End Sub 独自に同様の属性を作成するか、親子関係の テストメソッドとして作成するかで対応MSDN Blog:Visual Studio Team Test(http://blogs.msdn.com/b/vstsqualitytools/)にて独自に属性を拡張する対応案について記載あり(http://blogs.msdn.com/b/vstsqualitytools/archive/2009/09/04/extending-the-visual-studio-unit-test-type-part-2.aspx)
  35. 35. Imports System.ActivitiesPublic Class ActivityT Inherits System.Activities.CodeActivity Public Property InParam1 As InArgument(Of String) Public Property OutParam1 As OutArgument(Of Integer) Protected Overrides Sub Execute(context As CodeActivityContext) Dim inString = context.GetValue(Me.InParam1) Dim inStrInfo = New Globalization.StringInfo(inString) context.SetValue(Me.OutParam1, inStrInfo.LengthInTextElements) End SubEnd Classリファクタリング後再度テストを行いテストに通過するのを確認
  36. 36. ブックマークのテスト<Test()> WorkflowApplicationTest をPublic Sub TestBookmarkWorkflow() 利用したテストのサンプル Const BOOKMARKNAME = "TestBookmark1" Const SENDVALUE = "1" テストするアクティビティの生成 Dim testActivity As New ActivitySample 実行用 WorkflowInvoker の生成 Dim testAppliaction As WorkflowApplicationTest(Of ActivitySample) = Nothing Try 実行用 WorkflowApplication の生成 testAppliaction = WorkflowApplicationTest.Create(testActivity) 実行 testAppliaction.TestActivity() ブックマークの確認 Assert.IsTrue(testAppliaction.Bookmarks.Contains(BOOKMARKNAME)) Assert.AreEqual(BookmarkResumptionResult.Success, testAppliaction.TestWorkflowApplication.ResumeBookmark(BOOKMARKNAME, SENDVALUE)) 終了まで待機 Assert.IsTrue(testAppliaction.WaitForCompletedEvent) Finally testAppliaction.Tracking.Trace() ブックマークの状態確認と End Try ブックマークの呼出確認がEnd Sub 主なテスト内容となる
  37. 37. 永続化のテスト 永続化テスト用ヘルパークラス MemoryStore が用意されている  Microsoft.Activities.UnitTesting.Persistance.MemoryStore 現時点では WorkflowServiceTestHost で 自動利用されるだけで他からは利用できない  WorkflowApplicationTest クラスに永続化を 利用する仕組みが用意されていない SQL Server に永続化用環境を構築して テストするのがベター永続化環境構築用スクリプトはデフォルトで用意されている
  38. 38. この作業の繰り返しにてアクティビティの実装を行う WFにおける もう1つの 実装パターン Xamlのみで作成する 純粋なアクティビティ
  39. 39. Xaml のみで作成するアクティビティのサンプル
  40. 40. <Activity mc:Ignorable="sap" x:Class="Sequence1" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Core" xmlns:s3="clr-namespace:System;assembly=System.ServiceModel" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sg="clr-namespace:System.Globalization;assembly=mscorlib"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <x:Members> <x:Property Name="InParam1" Type="InArgument(x:String)" /> <x:Property Name="OutParam1" Type="OutArgument(x:Int32)" /> </x:Members> <this:Sequence1.InParam1> このような形で xml 形式 <InArgument x:TypeArguments="x:String"> <Literal x:TypeArguments="x:String" Value="" /> として記述できる </InArgument> </this:Sequence1.InParam1><sap:VirtualizedContainerService.HintSize>306,324</sap:VirtualizedContainerService.HintSize> <mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XMLnamespaces</mva:VisualBasic.Settings> <Sequence DisplayName="シーケンス" sap:VirtualizedContainerService.HintSize="266,284"> <Sequence.Variables> <Variable x:TypeArguments="sg:StringInfo" Name="InStrInfo" /> </Sequence.Variables>
  41. 41. Visual Studio 上では xaml ファイルでのワー クフローもクラスとして認識するExpress ではクラスとして認識しない
  42. 42. XamlInjector での呼出<TestMethod()> Public Sub TestMethodFromXaml() Const ORIGINAL_WORD = "Sample Word" Const RESULTVALUE = 11 XamlInjector にて動的に ワークフローを呼び出し Dim xl As New XamlInjector("Activity1.xaml") Dim testActivity = xl.GetActivity アクティビティを取得 Dim testInvoker As WorkflowInvokerTest = Nothing Try Activity クラスとして ワークフローへプロパティを設定 Dim inArgs As New Dictionary(Of String, Object) 取得できるので中身を inArgs.Add("InParam1", ORIGINAL_WORD) 気にしなくてよい 実行用 WorkflowInvoker の生成 testInvoker = New WorkflowInvokerTest(testActivity) 実行 Dim result = testInvoker.TestActivity(inArgs) 結果の確認 Assert.IsTrue(result.ContainsKey("OutParam1")) Assert.AreEqual(RESULTVALUE.ToString, result("OutParam1").ToString) Finally testInvoker.Tracking.Trace() End Try End Sub
  43. 43. XamlInjector での呼出<TestMethod()> Public Sub TestMethodFromXaml() Const ORIGINAL_WORD = "Sample Word" アクティビティのプロパティ Const RESULTVALUE = 11 設定と異なり引数での受渡しは Dim xl As New XamlInjector("Activity1.xaml") Dim testActivity = xl.GetActivity Dictionary を利用する Dim testInvoker As WorkflowInvokerTest = Nothing Try 引数は大文字小文字を ワークフローへプロパティを設定 Dim inArgs As New Dictionary(Of String, Object) 判別するので注意 inArgs.Add("InParam1", ORIGINAL_WORD) 実行用 WorkflowInvoker の生成 testInvoker = New WorkflowInvokerTest(testActivity) 実行 Dim result = testInvoker.TestActivity(inArgs) 結果の確認 Assert.IsTrue(result.ContainsKey("OutParam1")) Assert.AreEqual(RESULTVALUE.ToString, result("OutParam1").ToString) Finally testInvoker.Tracking.Trace() End Try End Sub
  44. 44. ワークフローサービスのテストテスト用サービスホスト• テスト方法はWCFクライアントでのアクセスと同様の 手順• 実際にサービスとして起動できる必要がある• Express の場合は Web 参照にてワークフローサービス の 情報を取得する必要があるモック• 送受信アクティビティを置換• サービスとして起動しなくてよい• 置換するアクティビティの数だけテストロジック量が増 える
  45. 45. テスト対象の ワークフローサービス渡された文字列の文字数をカウントし返却するシンプルなサービス
  46. 46. <"Sample Word", 11)> モックを利用したテストのサンプル<TestCase("𠮟 る", 2)>Public Sub TestServiceUseMock(ByVal orgWord As String, ByVal result As Integer) Dim xl As New XamlInjector("TestService.xamlx") 送受信アクティビティの置換 xl.ReplaceAll(GetType(Receive), GetType(ReceiveStub)) xl.ReplaceAll(GetType(Send), GetType(SendStub)) ダミーのメッセージを設定 Dim stubExtension As New MessagingStubExtension OperationName と stubExtension.EnqueueReceive( ServiceContracetName XName.Get("{http://tempuri.org/}IService"), "LengthCount", orgWord) の設定から記載 Dim svHost = WorkflowInvokerTest.Create(xl.GetWorkflowService.Body) svHost.Extensions.Add(stubExtension) Try svHost.TestActivity() Assert.AreEqual(2, stubExtension.Messages.Count) Assert.AreEqual(result, stubExtension.Messages(1).Content) Finally svHost.Tracking.Trace() End TryEnd Sub
  47. 47. <"Sample Word", 11)> モックを利用したテストのサンプル<TestCase("𠮟 る", 2)>Public Sub TestServiceUseMock(ByVal orgWord As String, ByVal result As Integer) Dim xl As New XamlInjector("TestService.xamlx") 送受信アクティビティの置換 xl.ReplaceAll(GetType(Receive), GetType(ReceiveStub)) xl.ReplaceAll(GetType(Send), GetType(SendStub)) ダミーのメッセージを設定 WorkflowInvokerTest で Dim stubExtension As New MessagingStubExtension stubExtension.EnqueueReceive( 通常通りにテストを行う XName.Get("{http://tempuri.org/}IService"), "LengthCount", orgWord) Dim svHost = WorkflowInvokerTest.Create(xl.GetWorkflowService.Body) svHost.Extensions.Add(stubExtension) Try svHost.TestActivity() Assert.AreEqual(2, stubExtension.Messages.Count) Assert.AreEqual(result, stubExtension.Messages(1).Content) Finally svHost.Tracking.Trace() End TryEnd Sub
  48. 48. まとめユニットテスト用ライブラリを利用する事で、 通常とほぼ同様に WF も TDD を行えますTDD で開発すると安心に繋がります特殊な要素が色々ありますが WF を 使ってみてください……
  49. 49. ご清聴ありがとうございました

×