Delphi ApplicationへのWinRunnerの適用手法の検討

Delphi ApplicationへのWinRunnerの適用手法の検討
オブジェクト認識の仕組み

オブジェクトの分類
Add-inの種類と概要

Add-in適用パターンの比較

コスト
業務フロー

表紙

Delphi ApplicationへのWinRunnerの適用手法の検討

ScriptGUI MAP

Application#### TSL(Test Script Language) ##### New Name
set_window ("New Name");edit_set ("Name", "New Name");button_press ("OK");

オブジェクト名称をで表す"New Name":{ class: window,label: "!.*",
MSW_class: TFormCreateNew }を元にオブジェクトを認識する"New Name".Name:{ class: edit,
MSW_class: TEdit,
dlph_name: EBoxProxyName }"New Name".OK:{ class: push_button,
dlph_name: ButtonOK }図１

Delphi ApplicationへのWinRunnerの適用手法の検討

Delphi ApplicationへのWinRunnerの対応

要件
・各オブジェクトをGUIマップに登録出来る（自動記録・学習）・スクリプトの記録／再生が可能

・標準的オブジェクト
・カスタムオブジェクト・認識不能オブジェクト

図2_0

Delphi ApplicationへのWinRunnerの適用手法の検討

WinRunner本体へのロード

Applicationへの組込

Script

テスト対象Application

Dlphiniｔ
WinRunner
本体

構 築 （Build)

Script（wrun.exe)
Dlphlib
Delphi
コンパイラ

記録関数(Dlph_ext.dll)

TestSrvr

Delphi Unit File
For WR Add in

Application

Application
Source file

図2

Delphi ApplicationへのWinRunnerの適用手法の検討##################################################### Map all standard Delphi classes####################################################
add_dlph_obj ("TForm","window", "class MSW_class dlph_name", "label","Count_objects", DLPH_OBJ);
add_dlph_obj ("TRadioGroup", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TDBRadioGroup", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TGroupBox", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TDBNavigator", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TImage", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TDBImage", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TBitbtn", "push_button", "class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TButton", "push_button", "class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TComboBox", "combobox", "class MSW_class dlph_name", "dlph_parent","Selection", DLPH_OBJ);
add_dlph_obj ("TDBComboBox", "combobox", "class MSW_class dlph_name", "dlph_parent","Selection", DLPH_OBJ);########################################################## Grid Objects#########################################################
add_dlph_obj ("TStringGrid","object", "class MSW_class dlph_name", "dlph_parent","", DLPH_GRID);
add_dlph_obj ("TDBGrid","object", "class MSW_class dlph_name", "dlph_parent","", DLPH_GRID);
add_dlph_obj ("TDBGridInplaceEdit","object", "class MSW_class dlph_parent", "","Enabled", DLPH_GRID);
add_dlph_obj ("TPopupGrid","object", "class MSW_class dlph_name", "dlph_parent","", DLPH_GRID);########################################################## Custmerszie Objects#########################################################
add_dlph_obj ("TPopupListbox","object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_REC_OBJ);
add_dlph_obj ("TPopupDataList","object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_REC_OBJ);
add_dlph_obj ("TDBLookupListBox", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_REC_OBJ);
add_dlph_obj ("TDBLookupComboBox", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_REC_OBJ);
add_dlph_obj ("TPanel", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_REC_OBJ);
add_dlph_obj ("TToolbar97", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_REC_OBJ);

図3

Delphi ApplicationへのWinRunnerの適用手法の検討

Operation

WinRunner

自動記録

図4

Delphi ApplicationへのWinRunnerの適用手法の検討

Operation

WinRunner

Input “Software Test” to Edit 1

自動記録

GUI MAP(TypeA)

GUI MAP(TypeA & B)

Form2.TEdit_0:{
class: edit,
MSW_class: TEdit,location: 0}
Form2.TEdit_1:{
class: edit,
MSW_class: TEdit,location: 1

Form2.Edit1:{
class: edit,
MSW_class: TEdit,
dlph_name: Edit1}
Form2.Edit2:{
class: edit,
MSW_class: TEdit,
dlph_name: Edit2}#### TSL(Test Script Language) ####

Input “Hardware Test” to Edit 2# Add-in Loaded(TypeA)
set_window ("Form2", 2);
edit_set ("TEdit_0", "Software Test");edit_set ("TEdit_1", "Hardware Test");# Add-in Loaded and TestSrvr(TypeA&B)
set_window ("Form2", 3);
edit_set ("Edit1", "Software Test");edit_set ("Edit2", "Hardware Test");

図5

Delphi ApplicationへのWinRunnerの適用手法の検討###########################Customized Object##########################
add_dlph_obj ("F8ToolBarClass", "toolbarwindow32", "class MSW_class dlph_name","dlph_parent","Enabled", DLPH_OBJ);

set_class_map("TToolBar", "toolbarwindow32");
set_record_attr("TToolBar", "class MSW_class", "label", "location");
set_record_method("TToolBar", RM_RECORD);

図6

Delphi ApplicationへのWinRunnerの適用手法の検討

あらかじめ仮想オブジェクトとして登録しておく
GUI MAP
Form4.SpeedButton:{class: push_button,virtual: TRUE,
x: 55,
y: 44,
width: 103,height: 30,
rows: 1,columns: 1}#### TSL(Test Script Language) ####
自動記録

button_press ("SpeedButton");Click “SpeedButton1”

図7

Delphi ApplicationへのWinRunnerの適用手法の検討WinRunner

Operation#### TSL(Test Script Language) ####
# Add-in Loaded & TestSrvr included Application
set_window ("Form3", 1);
dlph_panel_button_press ("Panel1","SpeedButton1",63,10);

自動記録
Click “SpeedButton1”# Add-in Loaded#No steps made#SpeedButtonは学習されない為、全く記録されない# No Add-in
set_window ("Form3", 3);
obj_mouse_click ("Panel1", 81, 44, LEFT);

図7_2

Delphi ApplicationへのWinRunnerの適用手法の検討#### TSL(Test Script Language) ####
#Pattern_A修正用初期化スクリプト---------------------------------------------------##Customized object
set_class_map("F8ToolBarClass", "toolbarwindow32");
set_record_attr("F8ToolBarClass", "class MSW_class", "label", "location");
set_record_method("F8ToolBarClass", RM_RECORD);
set_class_map("TF8CheckListBoxClass", "listbox");
set_record_attr("TF8CheckListBoxClass", "class MSW_class", "label", "location");
set_record_method("TF8CheckListBoxClass", RM_RECORD);
set_class_map("TF8Panel", "object");
set_record_attr("TF8Panel", "class MSW_class", "label", "location");
set_record_method("TF8Panel", RM_RECORD);
set_class_map("TF8Edit", "edit");
set_record_attr("TF8Edit", "class MSW_class", "label", "location");
set_record_method("TF8Edit", RM_RECORD);
set_class_map("TF8ComboBox", "combobox");
set_record_attr("TF8ComboBox", "class MSW_class", "label", "location");
set_record_method("TF8ComboBox", RM_RECORD);
set_class_map("TF8ListView", "syslistview32");
set_record_attr("TF8ListView", "class MSW_class", "label", "location");
set_record_method("TListView", RM_RECORD);##Delphi standard objectset_class_map("TToolBar", "toolbarwindow32");
set_record_attr("TToolBar", "class MSW_class", "label", "location");
set_record_method("TToolBar", RM_RECORD);
set_class_map("TSpinEdit", "object");
set_record_attr("TSpinEdit", "class MSW_class", "label", "location");
set_record_method("TSpinEdit", RM_RECORD);
set_class_map("TPanel", "object");
set_record_attr("TPanel", "class MSW_class", "label", "location");
set_record_method("TPanel", RM_RECORD);
set_class_map("TPageControl", "SysTabControl32");
set_record_attr("TPageControl", "class MSW_class", "label", "location");
set_record_method("TPageControl", RM_RECORD);
set_class_map("TComboBox", "combobox");
set_record_attr("TComboBox", "class MSW_class", "label", "location");
set_record_method("TComboBox", RM_RECORD);
set_class_map("TListBox", "listbox");
set_record_attr("TListBox", "class MSW_class", "label", "location");
set_record_method("TListBox", RM_RECORD);
set_class_map("TListView", "syslistview32");
set_record_attr("TListView", "class MSW_class", "label", "location");
set_record_method("TListView", RM_RECORD);
set_class_map("TTreeView", "systreeview32");set_record_attr("TTreeView", "class MSW_class", "label", "location");
set_record_method("TTreeView", RM_RECORD);#Pattern_B修正用初期化スクリプト---------------------------------------------------add_dlph_obj ("TF8CheckListBoxClass", "listbox", "class MSW_class dlph_name", "dlph_parent","Selection", DLPH_OBJ);
add_dlph_obj ("F8ToolBarClass", "toolbarwindow32", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TF8Panel", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TF8Edit", "edit", "class MSW_class dlph_name", "dlph_parent","Compare", DLPH_OBJ);
add_dlph_obj ("TF8ComboBox", "combobox", "class MSW_class dlph_name", "dlph_parent","Selection", DLPH_OBJ);
add_dlph_obj ("TListView","syslistview32", "class MSW_class dlph_name", "dlph_parent","Selection", DLPH_OBJ);
add_dlph_obj ("TToolBar", "toolbarwindow32", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);#dlpj_Panel_Button_Pressが記録をHookしてしまうのでここで再定義してやる必要有
add_dlph_obj ("TPanel", "object", "class MSW_class dlph_name", "dlph_parent", "Enabled", DLPH_OBJ);#Pattern_C修正用初期化スクリプト---------------------------------------------------add_dlph_obj ("TF8CheckListBoxClass", "listbox", "class MSW_class dlph_name", "dlph_parent","Selection", DLPH_OBJ);
add_dlph_obj ("F8ToolBarClass", "toolbarwindow32", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TF8Panel", "object", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);
add_dlph_obj ("TF8Edit", "edit", "class MSW_class dlph_name", "dlph_parent","Compare", DLPH_OBJ);
add_dlph_obj ("TF8ComboBox", "combobox", "class MSW_class dlph_name", "dlph_parent","Selection", DLPH_OBJ);
add_dlph_obj ("TListView","syslistview32", "class MSW_class dlph_name", "dlph_parent","Selection", DLPH_OBJ);
add_dlph_obj ("TToolBar", "toolbarwindow32", "class MSW_class dlph_name", "dlph_parent","Enabled", DLPH_OBJ);

図10

Delphi ApplicationへのWinRunnerの適用手法の検討

開発・Test Phase

開発
GroupApplication
修正

出荷 Phase

ベータ版
作成

製品版
作成

出荷作業

テスト結果報告

テスト実施

ベータ版
Application

TestGroup
テストスクリプト作成

自動テスト実施図11

Delphi ApplicationへのWinRunnerの適用手法の検討

開発・Test Phase

開発
GroupApplication
修正

テスト実施

出荷 Phase

ベータ版
作成

テスト依頼

製品版
作成

出荷作業

テスト結果報告

ベータ版
作成（Add-in Unit込）

ベータ版
Application

TestGroup
テストスクリプト作成

自動テスト実施図12

Delphi ApplicationへのWinRunnerの適用手法の検討

開発・Test Phase

開発
Group

出荷 Phase

ベータ版
作成（Test Unit 込）

Application
修正

製品版
作成

出荷作業

テスト結果報告

テスト実施

ベータ版
Application

TestGroup
テストスクリプト作成

自動テスト実施図13

Delphi ApplicationへのWinRunnerの適用手法の検討

図14

Delphi ApplicationへのWinRunnerの適用手法の検討

図15

Delphi ApplicationへのWinRunnerの適用手法の検討

Add-in
適用パターン

Pattern_A

GUIマップ
物理的記述
・メニュー項目を除く全てのオブジェクトがobjectクラスにマッピングされる(*1)。
・HWNDやコントロールIDが物理的記述に採用された場合、再生時認識不能。

Pattern_B・dlph_init内で定義済みのオブジェクトは各々最適なクラスにマッピングされる。
・カスタムオブジェクトは全てobjectクラスにマッピングされる。
このようなオブジェクトはPattern_Aと同様認識不能となる場合有り。

Pattern_C

同上

論理名

スクリプト

"クラス名" orほとんど全ての操作を"labelプロパティ"(*2) "obj_mouse_click" or "obj_type" で記録。
マッピングされたクラス固有の関数で記録。
button_press();
同上
eidt_set();tab_select_item(); 等Pattern_Bの内容に加え、Delphオブジェクトの PanelやGridの操作関数が記録される。
Nameプロパティ
dlph_panel_button_press();tbl_get_cell_data(); 等(*1)#32770等のOSに用意されたダイアログを除く(*2)labelプロパティは多くのDelphiオブジェクトには存在しないが、caption等がlabelとして採用されている

Add-in適用パターン
Pattern_A

修正方法
オブジェクト毎に類似クラスにマッピングする関数を初期化スクリプトに追加する。

Pattern_B

同上Pattern_C

同上

修正対象オブジェクト
ほぼ全てのオブジェクト
カスタムオブジェクト及び
dlph_initに含まれていないDelphiオブジェクト
同上

表2

Delphi ApplicationへのWinRunnerの適用手法の検討

Add-in
適用パターン
Pattern_A
Pattern_B
Pattern_C

テスト作成・維持コスト

テスト実行時コスト

ツール自体のコスト

×(*1)
○(*2)
◎(*3)

－－×(*4)

○(*5)
×(*6)
×(*6)

(*1) ほぼ全てのオブジェクトが自動ではobjectクラスとしてしか認識されない。
(*2) 標準Delphiオブジェクトに関しては最適なクラスにマッピングされる。
(*3) ・GridやPanelオブジェクトに対して、個別の便利な関数が使用可能となる。
・Nameプロパティを取得出来る。
(*4) ApplicationにTestUnitを組込んで、再構築する必要有り。詳細は”５．２ 業務フロー”参照。
(*5) WinRunner本体以外のコストは発生しない。
(*6) 組込み用TestUnit(TestSrvr)は別売り。購入及び維持費用が別途発生。

表4