カスタムコントロールのテスト-ワークベンチのチュートリアル(32bit)
SilkTest 14では、カスタムコントロールのメソッドを呼び出すことができるようになりました。実際にサンプルのアプリケーションを使用してカスタムコントロールのテストを行います。
カスタムコントロールのテストで実現できること、できないこと
カスタムコントロールのテストで、実現できることは次の通りです。
- カスタムコントロールが公開しているメソッドを、SilkTestから呼び出す
次のような機能はありません。
- カスタムコントロールに対する操作を記録する
- メソッド名などが不明なカスタムコントロールの操作を行う
カスタムコントロールのテストを実行する条件
SilkTest 14で、カスタムコントロールのテストを行うには、次の条件を満たしている必要があります。
- 使用しているカスタムコントロールを呼び出している実行ファイルが、.NET Form もしくはWPFであること。
- 使用しているカスタムコントロールのDLL名称と、ファイルが存在するディレクトリが判明していること
- カスタムコントロールの内容にアクセスしたり、操作を行うメソッドがわかっていること
- 呼び出し対象のメソッドを保持しているコントロールのオートメーションIDが判明していること
サンプルプログラムのダウンロードと解説
サンプルプログラムは次のリンクからダウンロードできます。
サンプルプログラム
サンプルプログラム(ソースコードのみ) (本チュートリアルでは使用しません)
サンプルプログラムを回答すると、次の2つのファイルが取得できます。
SilkAUT01.exe … テスト対象アプリケーション
JPNumBoxCtrl.dll … カスタムコントロール
このカスタムコントロールは、数字を漢字で表示する機能を持っています。実際に、このアプリケーションを起動し、単価と個数を入力し、[計算]ボタンを押して動作を確認します。
このカスタムコントロールには、2つのプロパティが存在し、公開されています。通常、この情報はカスタムコントロールのドキュメントに記載されている情報です。不明な場合、カスタムコントロールの作成者に問い合わせを行います。
- Value プロパティ (Read/Write)
このコントロールに対して、整数値を指定します。指定された値が、漢数字で表示されます。また、このコントロールから値が取得できます。
- Text プロパティ (Read only)
このコントロールに表示されている文字列を取得します。
標準の動作を確認
実際にアプリケーションを動作させ、SilkTestがカスタムコントロールをどのように認識するか、プロパティへのアクセスが可能かを確認します。
オブジェクトの認識
左の図は、アプリケーションを動作させ、Silk Test ワークベンチの識別ツールでオブジェクトを認識したときの画面です。
オブジェクトは、Controlとして認識されています。SilkTestは、この部品を画面のGUI部品であることは認識していますが、具体的にどのようなコントロールなのかは識別していません。
プロパティの取得
実際にこのアプリケーションを操作するスクリプトを記録し、コントロールのプロパティから値を取得できるかを確認します。
単価1980円x22個と入力するスクリプトを記録すると、次のようなスクリプトが生成されます。(環境により若干異なります)
Imports SilkTest.Ntf.WindowsForms
Public Module Main
Dim _desktop As Desktop = Agent.Desktop
Public Sub Main()
With _desktop.FormsWindow("Form1")
.SetActive()
.TextField("txtUnitPrice").SetPosition(New TextPosition(0, 0))
.TextField("txtUnitPrice").SetText("1980")
.TextField("txtUnitPrice").TypeKeys("<Tab>")
.TextField("txtCount").SetText("22")
.PushButton("button1").Select()
End With
End Sub
End Module
このスクリプトで、値が正しいかの検証をするため、値の取得を挿入します。取得した値は、ダイアログボックスに表示させます。
Imports System.Windows.Forms ' 追加
:
.PushButton("button1").Select()
Dim objText As String ' 追加
objText = .Control("//Control[@automationId='pict1']").Text ' 追加
MessageBox.Show("取得された値 = " + objText,"テスト",MessageBoxButtons.OK) ' 追加
End With
:
このスクリプトを実行しても、メッセージボックスにコントロールの値「四万三千五百六十」もしくは「43560」は表示されません。この値は、カスタムコントロールの中に隠ぺいされているためです。
この動作は、SilkTest 13.5までの標準的な動作です。SilkTest 14移行でも、特別な処理を加えない限り、このようにカスタムコントロールの内部にアクセスすることはできません。
Silk Test 14でカスタムコントロール対応を加える
必要な情報を集める
Silk Test 14でカスタムコントロールのテストをするために必要な情報を集めます。
- 使用しているカスタムコントロールのDLL名称とディレクトリ
アプリケーションがロードしているDLLの名称やディレクトリが不明な場合、カスタムコントロールのメーカに問い合わせてください。
今回のサンプルではDLL名がJPNumBoxCtrl.dll、ディレクトリは実行ファイルと同じディレクトリです。
- 値を取得するためのメソッド名
テスト対象アプリケーションがカスタムコントロールを呼び出す際のメソッド名です。通常、カスタムコントロールのドキュメントなどに記載されています。もちろん、カスタムコントロールの作成者は知っている情報です。
今回のサンプルでは、Valueとして整数値のget/set 、Textとして文字列のgetです。
- メソッドを実装しているコントロールのオートメーションID
これが最も見つけるのが困難な情報です。通常、Silk Testの識別ツールなどから求めていきますが、メソッド名がどのオートメーションIDに属しているかは外から見たときにわかりにく場合があります。たとえば、下の画像は今回のサンプルプログラムの例ですが、オートメーションIDは’lblPrice’と、’pict1′で2つあります。
lblPriceは、テスト対象のアプリケーションを作成した際につけたコントロール名、pict1はカスタムコントロールを作成した際につけた、内部コントロールの名前です。
メソッドがどちらに属するかは、カスタムコントロールの作り方に依存します。カスタムコントロールのソースコードが無い場合、トライアンドエラーで見つけるしか方法がありません。
今回のサンプルでは、オートメ-ションID lblPrice です。
テストスクリプトにカスタムコントロールのDLLを追加する
スクリプトのプロパティを開き、右クリックメニューから、.NET アセンブリ参照の追加を選択します。[参照...]ボタンを押して、カスタムコントロールのDLLを指定します。
スクリプト資産にアクセッサのクラスとSharedメソッドを追加する
スクリプト資産の先頭(Importsの後ろ)に、カスタムコントロールの値を取得するためのクラスと静的メソッドを定義します。Public Sharedで関数を定義することに注意してください。
Public Class JPNumBoxUtil
Public Shared Function GetValue(jpNum As JPNumBoxCtrl.JPNumLabel) As Integer
Return jpNum.Value
End Function
Public Shared Function SetValue(jpNum As JPNumBoxCtrl.JPNumLabel , i As Integer) As Integer
jpNum.Value = i
Return jpNum.Value
End Function
Public Shared Function GetText(jpNum As JPNumBoxCtrl.JPNumLabel) As String
Return jpNum.Text
End Function
End Class
このクラスは、テスト対象のアプリケーションにロードされて実行されます。
アクセッサのクラスをテスト対象のアプリケーションに読み込ませる
テストスクリプトの先頭など(アプリケーションのメインウインドウが取得できたあと)で、そのメインウインドウに前の手順で作ったクラスを無理矢理ロードさせます。
:
Public Module Main
Dim _desktop As Desktop = Agent.Desktop
Public Sub Main()
Dim mainWindow As FormsWindow ' 追加
mainWindow = _desktop.FormsWindow("Form1") ' 追加
With _desktop.FormsWindow("Form1")
.SetActive()
mainWindow.LoadAssembly(GetType(JPNumBoxUtil).Assembly.Location) ' 追加
.TextField("txtUnitPrice").SetPosition(New TextPosition(0, 0))
.TextField("txtUnitPrice").SetText("1980")
:
ここで、mainWindowという変数を用意し、このオブジェクトに対して、loadAssemblyというメソッドを呼び出してクラスを強制的にロードさせています。この操作で、テスト対象アプリケーションは、前の手順で作ったJPNumBoxUtilクラスのメソッドが使用できるようになっています。もちろん、テスト対象アプリケーションは自分のプロセス内に、クラスがインジェクションされたことを知りません。そのため、このクラスをテスト対象アプリケーションが呼び出すことはありません。
テスト対象アプリケーションに強制的にメソッドを実行させて結果を取得する
前述のように、テスト対象アプリケーション側にロードされたクラスは、このままではどこからも呼び出されません。そこで、SilkTestから、テスト対象アプリケーションを制御してロードされたクラスのメソッドを実行させます。
これには、まず、呼び出したいメソッドを定義しているオブジェクトを求め、そのオブジェクトと呼び出したいメソッドを組み合わせて、Invokeメソッドを呼び出します。(今回はソースコードの一部分だけを説明に使っています。ソースコードの全体は最後に示します)
Dim myJPNum = mainWindow.Control("@automationId='lblPrice'") ’(1)
Dim objText As String
objText = mainWindow.Invoke("JPNumBoxUtil.GetText",myJPNum) '(2)
(1)の行で、メインウインドウの中から、GetTextなど値を取得するメソッドを保持するコントロールを求めています。このオートメーションIDは、最初のステップで用意した、「求めるのが難しいかもしれないID」です。
(2)の行は、このメソッドを保持するコントロールと、アクセッサのクラス名の文字列を引数にして、メインウインドウのInvokeメソッドを呼んでいます。この操作で、メインウインドウは、手順3で知らないうちにロードされてしまった、アクセッサクラス(Public Class JPNumBoxUtil)を呼び出し、結果が取得できます。
これで、テストスクリプトから、カスタムコントロールから値を取得するという操作が完了します。
実際のスクリプトと実行例
スクリプト全体は、次のようになりました。
また、値の取得だけでなく設定も可能です。このスクリプトでは、さらに、テキストの値を設定する処理を mainWindow.Invoke(“JPNumBoxUtil.SetValue”,myJPNum,65535)として加えてあります。
Imports SilkTest.Ntf.WindowsForms
Imports System.Windows.Forms
Public Class JPNumBoxUtil
Public Shared Function GetValue(jpNum As JPNumBoxCtrl.JPNumLabel) As Integer
Return jpNum.Value
End Function
Public Shared Function SetValue(jpNum As JPNumBoxCtrl.JPNumLabel , i As Integer) As Integer
jpNum.Value = i
Return jpNum.Value
End Function
Public Shared Function GetText(jpNum As JPNumBoxCtrl.JPNumLabel) As String
Return jpNum.Text
End Function
End Class
Public Module Main
Dim _desktop As Desktop = Agent.Desktop
Public Sub Main()
Dim mainWindow As FormsWindow
mainWindow = _desktop.FormsWindow("Form1")
With _desktop.FormsWindow("Form1")
.SetActive()
mainWindow.LoadAssembly(GetType(JPNumBoxUtil).Assembly.Location)
.TextField("txtUnitPrice").SetPosition(New TextPosition(0, 0))
.TextField("txtUnitPrice").SetText("1980")
.TextField("txtUnitPrice").TypeKeys("<Tab>")
.TextField("txtCount").SetText("22")
.PushButton("button1").Select()
Dim myJPNum = mainWindow.Control("@automationId='lblPrice'")
Dim objText As String
objText = mainWindow.Invoke("JPNumBoxUtil.GetText",myJPNum)
Dim iValue As Integer
iValue = mainWindow.Invoke("JPNumBoxUtil.GetValue",myJPNum)
MessageBox.Show("取得された値 = " + objText + "(" + iValue.ToString() + ")","テスト",MessageBoxButtons.OK)
mainWindow.Invoke("JPNumBoxUtil.SetValue",myJPNum,65535)
End With
End Sub
End Module
このスクリプトを実行すると、画面は次のようになります。
当初、SilkTestのスクリプトから出力するダイアログは空白で、値が取得できませんでしたが、正しく値が取得できるようになりました。また、文字列としての値と、数値としての値が両方取得できています。
ダイアログをOKを押して閉じると、SilkTestのスクリプトからカスタムコントロールに値の設定を行っています。その結果、カスタムコントロール側の画面が変化しています。
免責事項
ここで紹介したスクリプトは説明のためのサンプルであり、製品の一部ではございません。スクリプトが実際に動作するか、御社業務に適合するかなどに関しまして、一切の保証はございません。
スクリプト、説明、その他すべてについて、無謬性は保障されません。
ここで紹介するスクリプトの一部、もしくは全部について、弊社に断りなく、御社スクリプトの内部に組み込み、そのままご利用頂いても構いません。
本スクリプトの一部もしくは全部を二次的著作物に対して引用する場合、著作権法の精神に基づき、適切な扱いを行ってください。