SlideShare a Scribd company logo
1 of 49
Workflow Foundation 4
into Test Driven Develop
                     Ahf(小尾 智之)
自己紹介
VB と SQL Server がメインの何でも屋
インディー団体を含むプロレス全般と
 クマ(クマー含む)やもふもふしたもの好き
 黙って宇宙戦艦ヤマト2199 は見ておけ
Workflow Foundation ソムリエが目標
@IT エンジニアライフで色々書いてます
おさらい
Workflow Foundation とは
おさらい:WF の特徴・概念
アクティビティと呼ばれる要素の集合
振舞い・手順をモデルとして保存・実行
 XML (WF3.x は xoml、WF4 は xaml)で
  保存される
長期間における実行をサポートしている
 永続化、ブックマーク、アンロード
 標準で SQL Server を容易に利用できる
デザイナ上でモデル作成する方法とロジッ
 ク上で全てを行う方法がある
GUI / CUI どちらも対応可能
おさらい:開発環境について
Express ではそのままだと無理
  デザインコンポーネント拡張が必要な為
  エディタを自前で用意すれば可能
WF 3.5
  Visual Studio 2005
    + ExtensionS for Windows WF
  Visual Studio 2008 Standard 以降
WF 4
  Visual Studio 2010 Professional 以降
おさらい:WF3.5 と 4
3.5 と 4 はクラス構成も
 変更され全くの別物
  基底クラスから全て異なる
3.5 で実装されたアク
 ティビティを4 環境で
 利用する特殊措置を提供
  Interop アクティビティ
  CodePrex で移行キットを
   提供…
  基本は作り直し
  WF 3.x を利用してないのなら
   気にしないのが幸せです
おさらい:WF4 での主な改善点
WF 3.x よりもパフォーマンス向上
 全面的に向上しすぎ
 今まではなんだったんだ




 参考:MSDN:Windows Workflow Foudation 4 のパフォーマンス
http://msdn.microsoft.com/ja-jp/library/gg281645.aspx
WF でユニットテスト
WF の単体テスト
 Visual Studio で利用する単体テスト
  プロジェクトでは WF の単体テストを
  対象にしていない
 テストプロジェクトから参照設定を行うと怒られる
 Visual Studio 11 においても同様




                クラスライブラリ
                 プロジェクトを
               利用する方法で回避
WF 固有の問題点

アクティビティを   WF ランタイム機
実行する方法が複        能
   数       としての永続化


入力待機等に用い
           ロジックがあると
   る
            は限らない
ブックマーク機能
アクティビティの実行
  WFアクティビティの実行方法は3通り
                       最もシンプルな実行方法。
WorkflowInvoker
                       ブックマークが利用できない

                       ワークフロー上のイベント
WorkflowApplication     トラップなどが行える

                       WorkflowApplication + Web
WorkflowServiceHost     サービスとして公開



     実際には IIS でのホスティングも関係
WF による永続化
標準機能として SQL Server による
 永続化をサポート
カスタマイズによる SQL Server 以外の
 DB やテキストファイル等へ永続化も可能
永続化機能はワークフローの内容と
 直接的な関係が薄い
待ち状態の際に永続化する制御は
 ワークフロー個別に記載するのではなく
 WF ランタイム側にて制御
ブックマーク
反応が戻されるまでワークフローの実行を
 一時停止し待機状態にするための仕組み
 状態遷移型ワークフロー等でよく利用
バックグランドでワークフローを
 起動させておき、フォアグランド側の
 アプリから通信を行わせる形にて利用する
ロジックのないアクティビティ
ワークフロー = アクティビティ
 であるので既存アクティビティを
 ワークフロー上に設置しただけのものも
 アクティビティとなる
コードが存在しないアクティビティを
 作ることができる
Visual Studio 等でビルドすれば
 通常のクラスとして利用できる
WF で TDD
NUnit や MSTest、xUnit など多くの
 テストフレームワークがあるので利用
アクティビティやワークフローの
 実行ロジックが毎回必要で結構な量に
  WF ランタイムを通した挙動を
   テストする必要がある
  ライブラリ化で対応は可能
サービスのテストも必要
  セルフホストのコードを用意するか
  IIS や IIS Express を利用するか
Microsoft.Activities.UnitTesting
CodePlex 上で公開されている WF 用
 ユニットテストライブラリ
作者は Microsoft の Ron Jacobs 氏
(http://blogs.msdn.com/b/rjacobs/)

 AppFabric 開発チームのシニア
  プログラムマネージャらしい
利用する事で簡易に WF における
 ユニットテストが行えるようになる
TDDの流れ
   仕様の作成

    テストの作成

         テスト

         コーディング

          リファクタリング
繰り返し行う
TDDの流れ

アクティビティの開
                仕様の作成

                 テストの作成


発                 テスト

                   コーディング

                    リファクタリング




 ワークフローの開発


  ワークフローの開発

       アクティビティ = ワークフロー
余談:VWD2010 の設定
 Visual Web Developer 2010 で Nunit を
  利用する場合は少し設定を行っておくと楽に
 1. [ツール]-[外部ツール]にて NUnit を登録
 2. [ツール]-[カスタマイズ]にてプロジェクトの
    右クリックメニューに NUnit を登録
 直接ソリューションエクスプローラ上から
  プロジェクト指定した形で NUnit が起動できる
TDD による WF 開発
テストシナリオ
渡された文字列の文字数をカウント
 するアクティビティの作成
ワークフローに変数または引数を2つ
InParam1:入力文字列用の引数
OutParam1:文字数のカウント結果
プロジェクトの作成

               アクティビティライブラリと
               して新規プロジェクト作成




VWD の場合は
クラスライブラリにて作成
テスト用プロジェクトの追加
                        作成
単体テストプロジェクトでは               クラスライブラリとして作成す
WF の単体テストを行えない                    る




                    参照の追加
アクティビティライブラリへの             MSTest または NUnit 等への参
    参照を追加                          照を追加

 MSTest を利用する場合は
 Microsoft.VisualStudio.QualityTools.UnitTestFramework
 への参照を追加する(参照設定ダイアログで検索すると表示される)
 Nunit を利用する場合は Nunit.framework への参照を追加する
NuGet でパッケージの追加
      Microsoft.Activities.UnitTesting を NuGet にて追加する




PM>Install-Package Microsoft.Activities.UnitTesting

 Professional 以上の VS か VWD の場合は NuGet にて
 それ以外の Express な場合は CodePlex よりダウンロードして参照を追加
テストの作成
Imports Nunit.Framework

Public Class UnitTest1

  <Test()>
  Public Sub TestMethod1()
  End Sub

End Class
                                                       NUnit
Imports Microsoft.VisualStudio.TestTools.UnitTesting

<TestClass()>
Public Class UnitTest1

  <TestMethod()>
  Public Sub TestMethod1()
  End Sub

End Class                                              MSTest
テストの実行



ビルド後に一度テストを実行
問題なく正常終了する事を確認
テストの作成
まずは要件を満たすテストを作成する

その際ビルドを通すために、アクティビティの
定義は同時に作成する

  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
ヘルパークラス

          テスト用ヘルパークラスでは
          NUnit 等と同様のメソッドや
          プロパティが定義されている


          AssertOutArgument
          プロパティなど WF 特有の
          プロパティが追加された形



          何らかのテストフレームワークを
          利用したことがあれば特に悩む
          ことはないと思われる
テスト用ロジックの記載
<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 Try

End Sub
テスト失敗を確認
ビルド後テストを実行し、テストが予定通り
「失敗」する事を確認する




                  ここからがスタート
コーディング
テストを通過できるようアクティビティの
コーディングを行う
Imports System.Activities

Public 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 Sub

End Class




規則上は「テストを通過するように単純に」処理を書くよう言われるが
あまり正直にやりすぎるのも微妙なところ・・・
テストとトラッキング
コーディング後にテストを実行し、テストに通過する事を確認




Finally                           Tracking.Trace を行う事で
   testInvoker.Tracking.Trace()   アクティビティのトラッキング情報が
End Try
                                  出力される
リファクタリング
                                                               サロゲートペア文字での
<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
                                                             コードを修正する
<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)
Imports System.Activities

Public 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 Sub

End Class




リファクタリング後
再度テストを行いテストに
通過するのを確認
ブックマークのテスト
<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
                                                               主なテスト内容となる
永続化のテスト
  永続化テスト用ヘルパークラス
   MemoryStore が用意されている
    Microsoft.Activities.UnitTesting.Persistance.MemoryStore
  現時点では WorkflowServiceTestHost で
   自動利用されるだけで他からは利用できない
    WorkflowApplicationTest クラスに永続化を
     利用する仕組みが用意されていない
  SQL Server に永続化用環境を構築して
   テストするのがベター
永続化環境構築用スクリプトはデフォルトで用意されている
この作業の繰り返しにてアクティビティの実装を行う


 WFにおける
 もう1つの
 実装パターン
          Xamlのみで作成する
          純粋なアクティビティ
Xaml のみで作成するアクティビティのサンプル
<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 XML
namespaces</mva:VisualBasic.Settings>
  <Sequence DisplayName="シーケンス" sap:VirtualizedContainerService.HintSize="266,284">
   <Sequence.Variables>
    <Variable x:TypeArguments="sg:StringInfo" Name="InStrInfo" />
   </Sequence.Variables>
Visual Studio 上では xaml ファイルでのワー
              クフローもクラスとして認識する




Express では
クラスとして認識しない
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
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
ワークフローサービスのテスト
テスト用サービスホスト

• テスト方法はWCFクライアントでのアクセスと同様の
  手順
• 実際にサービスとして起動できる必要がある
• Express の場合は Web 参照にてワークフローサービス
  の
  情報を取得する必要がある

モック

• 送受信アクティビティを置換
• サービスとして起動しなくてよい
• 置換するアクティビティの数だけテストロジック量が増
  える
テスト対象の
 ワークフローサービス

渡された文字列の文字数を
カウントし返却するシンプ
ルなサービス
<"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 Try

End Sub
<"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 Try

End Sub
まとめ
ユニットテスト用ライブラリを利用する事で、
 通常とほぼ同様に WF も TDD を行えます
TDD で開発すると安心に繋がります
特殊な要素が色々ありますが WF を
 使ってみてください……
ご清聴ありがとうございました

More Related Content

What's hot

Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようずOda Shinsuke
 
Try_to_writecode_practicaltest #atest_hack
Try_to_writecode_practicaltest #atest_hackTry_to_writecode_practicaltest #atest_hack
Try_to_writecode_practicaltest #atest_hackkimukou_26 Kimukou
 
xUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassxUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassTakuto Wada
 
JMeter によるパフォーマンステスト指南
JMeter によるパフォーマンステスト指南JMeter によるパフォーマンステスト指南
JMeter によるパフォーマンステスト指南じゅん なかざ
 
reg-suitとQA Wolfを活用したVisual Regression Test
reg-suitとQA Wolfを活用したVisual Regression Testreg-suitとQA Wolfを活用したVisual Regression Test
reg-suitとQA Wolfを活用したVisual Regression TestKazuyuki Tsuzisaki
 
リファクタリング読書会20120220
リファクタリング読書会20120220リファクタリング読書会20120220
リファクタリング読書会20120220Suguru Shirai
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜JustSystems Corporation
 
TDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaTDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaYuta Kawadai
 
Awsで実現するseleniumテスト高速術
Awsで実現するseleniumテスト高速術Awsで実現するseleniumテスト高速術
Awsで実現するseleniumテスト高速術finoue
 
テスティングフレームワークに入門してみた - Swift編
テスティングフレームワークに入門してみた - Swift編テスティングフレームワークに入門してみた - Swift編
テスティングフレームワークに入門してみた - Swift編Hisakuni Fujimoto
 
Selenium 触ってみよう
Selenium 触ってみようSelenium 触ってみよう
Selenium 触ってみようOda Shinsuke
 
Unit testで定時帰宅!
Unit testで定時帰宅!Unit testで定時帰宅!
Unit testで定時帰宅!Funato Takashi
 
Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能Hiroto Yamakawa
 
Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようずOda Shinsuke
 
Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Norito Agetsuma
 
Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Norito Agetsuma
 
初めての単体テスト
初めての単体テスト初めての単体テスト
初めての単体テストBasuke Suzuki
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料gaaupp
 
xUnit Test Patterns - Chapter11
xUnit Test Patterns - Chapter11xUnit Test Patterns - Chapter11
xUnit Test Patterns - Chapter11Takuto Wada
 

What's hot (20)

Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようず
 
Try_to_writecode_practicaltest #atest_hack
Try_to_writecode_practicaltest #atest_hackTry_to_writecode_practicaltest #atest_hack
Try_to_writecode_practicaltest #atest_hack
 
xUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassxUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase Class
 
JMeter によるパフォーマンステスト指南
JMeter によるパフォーマンステスト指南JMeter によるパフォーマンステスト指南
JMeter によるパフォーマンステスト指南
 
reg-suitとQA Wolfを活用したVisual Regression Test
reg-suitとQA Wolfを活用したVisual Regression Testreg-suitとQA Wolfを活用したVisual Regression Test
reg-suitとQA Wolfを活用したVisual Regression Test
 
リファクタリング読書会20120220
リファクタリング読書会20120220リファクタリング読書会20120220
リファクタリング読書会20120220
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
 
TDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaTDD勉強会キックオフ for Java
TDD勉強会キックオフ for Java
 
Awsで実現するseleniumテスト高速術
Awsで実現するseleniumテスト高速術Awsで実現するseleniumテスト高速術
Awsで実現するseleniumテスト高速術
 
テスティングフレームワークに入門してみた - Swift編
テスティングフレームワークに入門してみた - Swift編テスティングフレームワークに入門してみた - Swift編
テスティングフレームワークに入門してみた - Swift編
 
Selenium 触ってみよう
Selenium 触ってみようSelenium 触ってみよう
Selenium 触ってみよう
 
Unit testで定時帰宅!
Unit testで定時帰宅!Unit testで定時帰宅!
Unit testで定時帰宅!
 
Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能
 
Introduction to Spock
Introduction to SpockIntroduction to Spock
Introduction to Spock
 
Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようず
 
Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015Jbatch実践入門 #jdt2015
Jbatch実践入門 #jdt2015
 
Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点) Java Batch 仕様 (Public Review時点)
Java Batch 仕様 (Public Review時点)
 
初めての単体テスト
初めての単体テスト初めての単体テスト
初めての単体テスト
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料
 
xUnit Test Patterns - Chapter11
xUnit Test Patterns - Chapter11xUnit Test Patterns - Chapter11
xUnit Test Patterns - Chapter11
 

Viewers also liked

特定支出控除の話
特定支出控除の話特定支出控除の話
特定支出控除の話Tomoyuki Obi
 
WF4 + WMI + PS + αで運用管理
WF4 + WMI + PS + αで運用管理WF4 + WMI + PS + αで運用管理
WF4 + WMI + PS + αで運用管理Tomoyuki Obi
 
4º primaria : pasatiempos matematicas
4º  primaria : pasatiempos matematicas4º  primaria : pasatiempos matematicas
4º primaria : pasatiempos matematicasMaria Trujillo
 

Viewers also liked (10)

特定支出控除の話
特定支出控除の話特定支出控除の話
特定支出控除の話
 
WF4 + WMI + PS + αで運用管理
WF4 + WMI + PS + αで運用管理WF4 + WMI + PS + αで運用管理
WF4 + WMI + PS + αで運用管理
 
Lt 110205
Lt 110205Lt 110205
Lt 110205
 
Clrh 20140301
Clrh 20140301Clrh 20140301
Clrh 20140301
 
Lt 20130302 1
Lt 20130302 1Lt 20130302 1
Lt 20130302 1
 
Clrh 111015 wf45
Clrh 111015 wf45Clrh 111015 wf45
Clrh 111015 wf45
 
Clrh 20140906 lt
Clrh 20140906 ltClrh 20140906 lt
Clrh 20140906 lt
 
Lt 20120901
Lt 20120901Lt 20120901
Lt 20120901
 
Lt 20130209
Lt 20130209Lt 20130209
Lt 20130209
 
4º primaria : pasatiempos matematicas
4º  primaria : pasatiempos matematicas4º  primaria : pasatiempos matematicas
4º primaria : pasatiempos matematicas
 

Similar to CLRH_120414_WFTDD

Tokyor14 - R言語でユニットテスト
Tokyor14 - R言語でユニットテストTokyor14 - R言語でユニットテスト
Tokyor14 - R言語でユニットテストYohei Sato
 
実践で学ぶ、効率的な自動テストスクリプトのメンテナンス
実践で学ぶ、効率的な自動テストスクリプトのメンテナンス実践で学ぶ、効率的な自動テストスクリプトのメンテナンス
実践で学ぶ、効率的な自動テストスクリプトのメンテナンスNozomi Ito
 
Introduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGoodIntroduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGoodAtsuhiro Kubo
 
Azure DevOps Online Vol.3 - Inside Azure Pipelines
Azure DevOps Online Vol.3 - Inside Azure PipelinesAzure DevOps Online Vol.3 - Inside Azure Pipelines
Azure DevOps Online Vol.3 - Inside Azure PipelinesKazushi Kamegawa
 
Getting Started with Testing using PHPUnit
Getting Started with Testing using PHPUnitGetting Started with Testing using PHPUnit
Getting Started with Testing using PHPUnitAtsuhiro Kubo
 
Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識shigeya
 
GroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackGroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackTakahiro Yoshimura
 
【JaSST'11 Tokyo】 テスト イノベーション
【JaSST'11 Tokyo】 テスト イノベーション【JaSST'11 Tokyo】 テスト イノベーション
【JaSST'11 Tokyo】 テスト イノベーション智治 長沢
 
20170625 JXUG Fukuoka 発表資料 : Unit / UI Testing - Xamarin
20170625 JXUG Fukuoka 発表資料 : Unit / UI Testing - Xamarin20170625 JXUG Fukuoka 発表資料 : Unit / UI Testing - Xamarin
20170625 JXUG Fukuoka 発表資料 : Unit / UI Testing - XamarinTakeshi Fujimoto
 
PHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めようPHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めようYuya Takeyama
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~normalian
 
Entity Framework 5.0 deep dive
Entity Framework 5.0 deep diveEntity Framework 5.0 deep dive
Entity Framework 5.0 deep diveAtsushi Fukui
 
Eclipse を使った java 開発 111126 杉浦
Eclipse を使った java 開発 111126 杉浦Eclipse を使った java 開発 111126 杉浦
Eclipse を使った java 開発 111126 杉浦urasandesu
 
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】 Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】 智治 長沢
 
JavaOne2013報告会 JavaFX Update
JavaOne2013報告会 JavaFX UpdateJavaOne2013報告会 JavaFX Update
JavaOne2013報告会 JavaFX UpdateTakashi Aoe
 

Similar to CLRH_120414_WFTDD (20)

Tokyor14 - R言語でユニットテスト
Tokyor14 - R言語でユニットテストTokyor14 - R言語でユニットテスト
Tokyor14 - R言語でユニットテスト
 
実践で学ぶ、効率的な自動テストスクリプトのメンテナンス
実践で学ぶ、効率的な自動テストスクリプトのメンテナンス実践で学ぶ、効率的な自動テストスクリプトのメンテナンス
実践で学ぶ、効率的な自動テストスクリプトのメンテナンス
 
Clrh 20121215
Clrh 20121215Clrh 20121215
Clrh 20121215
 
Introduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGoodIntroduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGood
 
CruiseControl.NET設置
CruiseControl.NET設置CruiseControl.NET設置
CruiseControl.NET設置
 
Lt 111217
Lt 111217Lt 111217
Lt 111217
 
Azure DevOps Online Vol.3 - Inside Azure Pipelines
Azure DevOps Online Vol.3 - Inside Azure PipelinesAzure DevOps Online Vol.3 - Inside Azure Pipelines
Azure DevOps Online Vol.3 - Inside Azure Pipelines
 
Getting Started with Testing using PHPUnit
Getting Started with Testing using PHPUnitGetting Started with Testing using PHPUnit
Getting Started with Testing using PHPUnit
 
Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識
 
GroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackGroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hack
 
【JaSST'11 Tokyo】 テスト イノベーション
【JaSST'11 Tokyo】 テスト イノベーション【JaSST'11 Tokyo】 テスト イノベーション
【JaSST'11 Tokyo】 テスト イノベーション
 
20170625 JXUG Fukuoka 発表資料 : Unit / UI Testing - Xamarin
20170625 JXUG Fukuoka 発表資料 : Unit / UI Testing - Xamarin20170625 JXUG Fukuoka 発表資料 : Unit / UI Testing - Xamarin
20170625 JXUG Fukuoka 発表資料 : Unit / UI Testing - Xamarin
 
PHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めようPHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めよう
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 
Entity Framework 5.0 deep dive
Entity Framework 5.0 deep diveEntity Framework 5.0 deep dive
Entity Framework 5.0 deep dive
 
Clrh 110827 wfho
Clrh 110827 wfhoClrh 110827 wfho
Clrh 110827 wfho
 
Nds#24 単体テスト
Nds#24 単体テストNds#24 単体テスト
Nds#24 単体テスト
 
Eclipse を使った java 開発 111126 杉浦
Eclipse を使った java 開発 111126 杉浦Eclipse を使った java 開発 111126 杉浦
Eclipse を使った java 開発 111126 杉浦
 
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】 Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】
 
JavaOne2013報告会 JavaFX Update
JavaOne2013報告会 JavaFX UpdateJavaOne2013報告会 JavaFX Update
JavaOne2013報告会 JavaFX Update
 

More from Tomoyuki Obi

それは本当にAutomate? 改めて考えるPower Automate
それは本当にAutomate? 改めて考えるPower Automateそれは本当にAutomate? 改めて考えるPower Automate
それは本当にAutomate? 改めて考えるPower AutomateTomoyuki Obi
 
Miniacs Power Automate
Miniacs Power AutomateMiniacs Power Automate
Miniacs Power AutomateTomoyuki Obi
 
Work Automate with Power Automate
Work Automate with Power AutomateWork Automate with Power Automate
Work Automate with Power AutomateTomoyuki Obi
 
JSON Value into Power Automate
JSON Value into Power AutomateJSON Value into Power Automate
JSON Value into Power AutomateTomoyuki Obi
 
CodelessDevelop using iPaas
CodelessDevelop using iPaasCodelessDevelop using iPaas
CodelessDevelop using iPaasTomoyuki Obi
 
20190727_DevelopUseiPaas
20190727_DevelopUseiPaas20190727_DevelopUseiPaas
20190727_DevelopUseiPaasTomoyuki Obi
 
Logic Apps/Flow Update Summary
Logic Apps/Flow Update SummaryLogic Apps/Flow Update Summary
Logic Apps/Flow Update SummaryTomoyuki Obi
 
decode2019_HandsOn_Flow_04
decode2019_HandsOn_Flow_04decode2019_HandsOn_Flow_04
decode2019_HandsOn_Flow_04Tomoyuki Obi
 
decode2019_HandsOn_Flow_03
decode2019_HandsOn_Flow_03decode2019_HandsOn_Flow_03
decode2019_HandsOn_Flow_03Tomoyuki Obi
 
decode2019_HandsOn_Flow_02
decode2019_HandsOn_Flow_02decode2019_HandsOn_Flow_02
decode2019_HandsOn_Flow_02Tomoyuki Obi
 
decode2019_HandsOn_Flow_01
decode2019_HandsOn_Flow_01decode2019_HandsOn_Flow_01
decode2019_HandsOn_Flow_01Tomoyuki Obi
 
20190427 global azurebootcamp
20190427 global azurebootcamp20190427 global azurebootcamp
20190427 global azurebootcampTomoyuki Obi
 
20181215 PowerApps + Flow Handson
20181215 PowerApps + Flow Handson20181215 PowerApps + Flow Handson
20181215 PowerApps + Flow HandsonTomoyuki Obi
 
20181120 HowtoFlow
20181120 HowtoFlow20181120 HowtoFlow
20181120 HowtoFlowTomoyuki Obi
 
20180929 lowcode developlogicflow
20180929 lowcode developlogicflow20180929 lowcode developlogicflow
20180929 lowcode developlogicflowTomoyuki Obi
 
20180721 First Challenge Logicflow
20180721 First Challenge Logicflow20180721 First Challenge Logicflow
20180721 First Challenge LogicflowTomoyuki Obi
 
20180630 data transformationusinglogicflow
20180630 data transformationusinglogicflow20180630 data transformationusinglogicflow
20180630 data transformationusinglogicflowTomoyuki Obi
 
Create Bot using LogicApps
Create Bot using LogicAppsCreate Bot using LogicApps
Create Bot using LogicAppsTomoyuki Obi
 

More from Tomoyuki Obi (20)

それは本当にAutomate? 改めて考えるPower Automate
それは本当にAutomate? 改めて考えるPower Automateそれは本当にAutomate? 改めて考えるPower Automate
それは本当にAutomate? 改めて考えるPower Automate
 
Only Logic Apps
Only Logic AppsOnly Logic Apps
Only Logic Apps
 
This is iPaas
This is iPaasThis is iPaas
This is iPaas
 
Miniacs Power Automate
Miniacs Power AutomateMiniacs Power Automate
Miniacs Power Automate
 
Work Automate with Power Automate
Work Automate with Power AutomateWork Automate with Power Automate
Work Automate with Power Automate
 
JSON Value into Power Automate
JSON Value into Power AutomateJSON Value into Power Automate
JSON Value into Power Automate
 
CodelessDevelop using iPaas
CodelessDevelop using iPaasCodelessDevelop using iPaas
CodelessDevelop using iPaas
 
20190727_DevelopUseiPaas
20190727_DevelopUseiPaas20190727_DevelopUseiPaas
20190727_DevelopUseiPaas
 
Logic Apps/Flow Update Summary
Logic Apps/Flow Update SummaryLogic Apps/Flow Update Summary
Logic Apps/Flow Update Summary
 
decode2019_HandsOn_Flow_04
decode2019_HandsOn_Flow_04decode2019_HandsOn_Flow_04
decode2019_HandsOn_Flow_04
 
decode2019_HandsOn_Flow_03
decode2019_HandsOn_Flow_03decode2019_HandsOn_Flow_03
decode2019_HandsOn_Flow_03
 
decode2019_HandsOn_Flow_02
decode2019_HandsOn_Flow_02decode2019_HandsOn_Flow_02
decode2019_HandsOn_Flow_02
 
decode2019_HandsOn_Flow_01
decode2019_HandsOn_Flow_01decode2019_HandsOn_Flow_01
decode2019_HandsOn_Flow_01
 
20190427 global azurebootcamp
20190427 global azurebootcamp20190427 global azurebootcamp
20190427 global azurebootcamp
 
20181215 PowerApps + Flow Handson
20181215 PowerApps + Flow Handson20181215 PowerApps + Flow Handson
20181215 PowerApps + Flow Handson
 
20181120 HowtoFlow
20181120 HowtoFlow20181120 HowtoFlow
20181120 HowtoFlow
 
20180929 lowcode developlogicflow
20180929 lowcode developlogicflow20180929 lowcode developlogicflow
20180929 lowcode developlogicflow
 
20180721 First Challenge Logicflow
20180721 First Challenge Logicflow20180721 First Challenge Logicflow
20180721 First Challenge Logicflow
 
20180630 data transformationusinglogicflow
20180630 data transformationusinglogicflow20180630 data transformationusinglogicflow
20180630 data transformationusinglogicflow
 
Create Bot using LogicApps
Create Bot using LogicAppsCreate Bot using LogicApps
Create Bot using LogicApps
 

Recently uploaded

TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 

Recently uploaded (8)

TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 

CLRH_120414_WFTDD

  • 1. Workflow Foundation 4 into Test Driven Develop Ahf(小尾 智之)
  • 2. 自己紹介 VB と SQL Server がメインの何でも屋 インディー団体を含むプロレス全般と クマ(クマー含む)やもふもふしたもの好き  黙って宇宙戦艦ヤマト2199 は見ておけ Workflow Foundation ソムリエが目標 @IT エンジニアライフで色々書いてます
  • 4. おさらい:WF の特徴・概念 アクティビティと呼ばれる要素の集合 振舞い・手順をモデルとして保存・実行  XML (WF3.x は xoml、WF4 は xaml)で 保存される 長期間における実行をサポートしている  永続化、ブックマーク、アンロード  標準で SQL Server を容易に利用できる デザイナ上でモデル作成する方法とロジッ ク上で全てを行う方法がある GUI / CUI どちらも対応可能
  • 5. おさらい:開発環境について Express ではそのままだと無理  デザインコンポーネント拡張が必要な為  エディタを自前で用意すれば可能 WF 3.5  Visual Studio 2005 + ExtensionS for Windows WF  Visual Studio 2008 Standard 以降 WF 4  Visual Studio 2010 Professional 以降
  • 6. おさらい:WF3.5 と 4 3.5 と 4 はクラス構成も 変更され全くの別物  基底クラスから全て異なる 3.5 で実装されたアク ティビティを4 環境で 利用する特殊措置を提供  Interop アクティビティ  CodePrex で移行キットを 提供…  基本は作り直し  WF 3.x を利用してないのなら 気にしないのが幸せです
  • 7. おさらい:WF4 での主な改善点 WF 3.x よりもパフォーマンス向上  全面的に向上しすぎ  今まではなんだったんだ 参考:MSDN:Windows Workflow Foudation 4 のパフォーマンス http://msdn.microsoft.com/ja-jp/library/gg281645.aspx
  • 9. WF の単体テスト  Visual Studio で利用する単体テスト プロジェクトでは WF の単体テストを 対象にしていない  テストプロジェクトから参照設定を行うと怒られる  Visual Studio 11 においても同様 クラスライブラリ プロジェクトを 利用する方法で回避
  • 10. WF 固有の問題点 アクティビティを WF ランタイム機 実行する方法が複 能 数 としての永続化 入力待機等に用い ロジックがあると る は限らない ブックマーク機能
  • 11. アクティビティの実行 WFアクティビティの実行方法は3通り  最もシンプルな実行方法。 WorkflowInvoker  ブックマークが利用できない  ワークフロー上のイベント WorkflowApplication トラップなどが行える  WorkflowApplication + Web WorkflowServiceHost サービスとして公開 実際には IIS でのホスティングも関係
  • 12. WF による永続化 標準機能として SQL Server による 永続化をサポート カスタマイズによる SQL Server 以外の DB やテキストファイル等へ永続化も可能 永続化機能はワークフローの内容と 直接的な関係が薄い 待ち状態の際に永続化する制御は ワークフロー個別に記載するのではなく WF ランタイム側にて制御
  • 14. ロジックのないアクティビティ ワークフロー = アクティビティ であるので既存アクティビティを ワークフロー上に設置しただけのものも アクティビティとなる コードが存在しないアクティビティを 作ることができる Visual Studio 等でビルドすれば 通常のクラスとして利用できる
  • 15. WF で TDD NUnit や MSTest、xUnit など多くの テストフレームワークがあるので利用 アクティビティやワークフローの 実行ロジックが毎回必要で結構な量に  WF ランタイムを通した挙動を テストする必要がある  ライブラリ化で対応は可能 サービスのテストも必要  セルフホストのコードを用意するか  IIS や IIS Express を利用するか
  • 16. Microsoft.Activities.UnitTesting CodePlex 上で公開されている WF 用 ユニットテストライブラリ 作者は Microsoft の Ron Jacobs 氏 (http://blogs.msdn.com/b/rjacobs/) AppFabric 開発チームのシニア プログラムマネージャらしい 利用する事で簡易に WF における ユニットテストが行えるようになる
  • 17. TDDの流れ 仕様の作成 テストの作成 テスト コーディング リファクタリング 繰り返し行う
  • 18. TDDの流れ アクティビティの開 仕様の作成 テストの作成 発 テスト コーディング リファクタリング ワークフローの開発 ワークフローの開発 アクティビティ = ワークフロー
  • 19. 余談:VWD2010 の設定  Visual Web Developer 2010 で Nunit を 利用する場合は少し設定を行っておくと楽に 1. [ツール]-[外部ツール]にて NUnit を登録 2. [ツール]-[カスタマイズ]にてプロジェクトの 右クリックメニューに NUnit を登録  直接ソリューションエクスプローラ上から プロジェクト指定した形で NUnit が起動できる
  • 22. プロジェクトの作成 アクティビティライブラリと して新規プロジェクト作成 VWD の場合は クラスライブラリにて作成
  • 23. テスト用プロジェクトの追加 作成 単体テストプロジェクトでは クラスライブラリとして作成す WF の単体テストを行えない る 参照の追加 アクティビティライブラリへの MSTest または NUnit 等への参 参照を追加 照を追加 MSTest を利用する場合は Microsoft.VisualStudio.QualityTools.UnitTestFramework への参照を追加する(参照設定ダイアログで検索すると表示される) Nunit を利用する場合は Nunit.framework への参照を追加する
  • 24. NuGet でパッケージの追加 Microsoft.Activities.UnitTesting を NuGet にて追加する PM>Install-Package Microsoft.Activities.UnitTesting Professional 以上の VS か VWD の場合は NuGet にて それ以外の Express な場合は CodePlex よりダウンロードして参照を追加
  • 25. テストの作成 Imports Nunit.Framework Public Class UnitTest1 <Test()> Public Sub TestMethod1() End Sub End Class NUnit Imports Microsoft.VisualStudio.TestTools.UnitTesting <TestClass()> Public Class UnitTest1 <TestMethod()> Public Sub TestMethod1() End Sub End Class MSTest
  • 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. ヘルパークラス テスト用ヘルパークラスでは NUnit 等と同様のメソッドや プロパティが定義されている AssertOutArgument プロパティなど WF 特有の プロパティが追加された形 何らかのテストフレームワークを 利用したことがあれば特に悩む ことはないと思われる
  • 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 Try End Sub
  • 31. コーディング テストを通過できるようアクティビティの コーディングを行う Imports System.Activities Public 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 Sub End Class 規則上は「テストを通過するように単純に」処理を書くよう言われるが あまり正直にやりすぎるのも微妙なところ・・・
  • 32. テストとトラッキング コーディング後にテストを実行し、テストに通過する事を確認 Finally Tracking.Trace を行う事で testInvoker.Tracking.Trace() アクティビティのトラッキング情報が End Try 出力される
  • 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. <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. Imports System.Activities Public 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 Sub End Class リファクタリング後 再度テストを行いテストに 通過するのを確認
  • 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. 永続化のテスト 永続化テスト用ヘルパークラス MemoryStore が用意されている  Microsoft.Activities.UnitTesting.Persistance.MemoryStore 現時点では WorkflowServiceTestHost で 自動利用されるだけで他からは利用できない  WorkflowApplicationTest クラスに永続化を 利用する仕組みが用意されていない SQL Server に永続化用環境を構築して テストするのがベター 永続化環境構築用スクリプトはデフォルトで用意されている
  • 38. この作業の繰り返しにてアクティビティの実装を行う WFにおける もう1つの 実装パターン Xamlのみで作成する 純粋なアクティビティ
  • 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 XML namespaces</mva:VisualBasic.Settings> <Sequence DisplayName="シーケンス" sap:VirtualizedContainerService.HintSize="266,284"> <Sequence.Variables> <Variable x:TypeArguments="sg:StringInfo" Name="InStrInfo" /> </Sequence.Variables>
  • 41. Visual Studio 上では xaml ファイルでのワー クフローもクラスとして認識する Express では クラスとして認識しない
  • 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. 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. ワークフローサービスのテスト テスト用サービスホスト • テスト方法はWCFクライアントでのアクセスと同様の 手順 • 実際にサービスとして起動できる必要がある • Express の場合は Web 参照にてワークフローサービス の 情報を取得する必要がある モック • 送受信アクティビティを置換 • サービスとして起動しなくてよい • 置換するアクティビティの数だけテストロジック量が増 える
  • 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 Try End Sub
  • 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 Try End Sub
  • 48. まとめ ユニットテスト用ライブラリを利用する事で、 通常とほぼ同様に WF も TDD を行えます TDD で開発すると安心に繋がります 特殊な要素が色々ありますが WF を 使ってみてください……