1. 程式人生 > >擴充套件 Rational Functional Tester 的物件識別技術

擴充套件 Rational Functional Tester 的物件識別技術

RFT 物件

從開發的角度看,GUI 通常都是基於某一 GUI 開發庫(SWT/SWING/AWT),這些庫通常是按照面向物件的方式進行建模的,它將每一個 GUI 元素對映成該庫中某一個類的物件。

從測試的角度看,所有的 GUI 元素,無論基於何種 GUI 庫,都被 RFT 對映成物件,RFT 提供一個物件模型框架管理各種 GUI 元素。

圖 1 是一個典型的基於 SWT 開發的 GUI,對於其中的一個按鈕,在開發者看來,它就是 SWT 庫中 Button 類的一個物件;但是 RFT 並不區分這是 SWT 庫中的按鈕,或者是其他 GUI 庫的按鈕,它都被對映成 RFT 物件模型中 GuiTestObject 物件。

在用 RFT 提供的 Inspector 工具獲取 GUI 元素時,需要用到開發模型。而進行 RFT 指令碼開發時,又需要用到 RFT 物件模型。熟練掌握兩種物件模型,對提高 RFT 自動化測試效率非常有幫助。

基於 RFT 的自動化測試,都會採用 IBM 推薦的 ITCL 框架。在這個框架下,所有的指令碼被劃分為三個層次:物件層,任務層,用例層。物件識別就是在 RFT 的物件模型框架下,得到被測程式的 GUI 物件。它是物件層開發中最核心的任務。

常用的 RFT 的物件識別技術可以分為兩大類:靜態識別與動態識別。動態和靜態方法各有優缺點,靜態方法識別效率高、開發成本比較低,但是指令碼的可維護性比較差;而動態方法剛好相反。

採用常用的物件識別技術,可以識別出大部分的 GUI 元素,但有時也會遇到 RFT 無法識別的 GUI 元素,事實上識別這類用常用物件識別技術無法識別的 GUI 元素佔用了 RFT 指令碼開發的大部分時間。

RFT 中一個非常重要的根介面是 IGraphical 介面,它定義了針對 GUI 元素的所有標準操作(click,doubleclick,drag 等)。另外一個非常重要的根類是 GuiTestObject,它繼承自 TestObject 並實現了 IGraphical 介面。常用物件識別技術中 GUI 元素都是被對映為 GuiTestObject 物件。它們在 RFT 物件模型中的位置如圖 2 所示。靈活運用這些類、介面及其方法,能夠極大地擴充套件 RFT 物件識別的功能。

  • 問題描述

使用 RFT 經常聽到的一個謬論就是 RFT 只能測試基於 java 的 GUI 程式,對於 C/C++ 或者 windows 標準控制元件,RFT 無法識別。事實上,RFT 提供了 IWindow 介面用於識別平臺相關的控制元件。

  • IWindow 介面介紹

從圖 2 中可以看出,IWindow 介面也繼承自 IGraphical 介面,從這點看,IWindow 介面具有與 GuiTestObject 類似的功能。

使用 IWindow 介面能夠識別平臺相關的 GUI 控制元件,但是其介面函式的具體實現與平臺相關,windows 與 linux 上的實現就不一樣,可以通過下述方法判斷具體的平臺,本文將主要分析 windows 上的應用。


清單 1

  • 典型應用

圖 3 是記事本的“頁面設定”對話方塊,是一個 windows 原始窗體。如何識別這個窗體,並點選“確定”按鈕呢?基於 RFT 的實現方法如下:


確定物件識別的起始點。通常選取最上層窗體作為物件識別的起始點,具體方法如下所示:


清單 2

這些方法都返回一個 IWindow 介面的陣列,每一個數組元素代表一個頂層視窗,並且這些視窗之間是互相獨立的。

識別符合要求的頂層視窗,即“頁面設定”對話方塊。IWindow 介面提供了兩個方法:getText() 與 getWindowClassName() 來實現。對於窗體,getText() 返回窗體的標題;對於控制元件,getText() 返回控制元件的文字。getWindowClassName() 返回 win32 標準控制元件名。如何知道被測程式的標準控制元件名呢?在 windows 上有許多工具,例如下文中將提到的 AutoIt 以及 Visual Studio 提供的 Spy++。圖 4 是用 AutoIt 得到的 GUI 元素的屬性。

對頂層窗體陣列根據文字值和標準控制元件名進行匹配,則可以識別出符合要求的頂層窗體。這兩個方法均返回字串,為了提高識別的效率,通常對這些字串進行正則表示式匹配。具體用法如下,引數 sCaption 表示窗體的標題,sWindowClassName 表示窗體的 Win32 標準類名。


清單 3

識別窗體內的控制元件,即“確定”按鈕。以頂層視窗為起點,通過 IWindow 提供的 getChildren() 函式可以得到內嵌在頂層窗體的 GUI 控制元件(如 button,label 等),該方法返回 IWindow 介面的陣列,對陣列元素根據文字值和標準控制元件名進行匹配,即可識別出內嵌的控制元件。識別內嵌控制元件的方法如下,引數 iTopwin 表示頂層窗體,sCtrlText 表示控制元件的文字值,sCtrlClassName 表示控制元件的 Win32 標準類名。


清單 4


IWindow 還提供了 getOwned() 方法,可以得到出頂層窗體擁有的子窗體(如模式對話方塊等)。

完成點選“頁面設定”窗體中“確定”按鈕的 RFT 指令碼如下。

清單 5


  • 問題描述

在進行 GUI 自動化測試時,一個經常遇到的問題就是如何測試開發者定製的控制元件?通常一組定製的控制元件,是作為一個整體被 RFT 識別出來,你可以對這個整體作一些操作,但是如何識別出每一個具體的定製控制元件呢?可以使用 TestObject 類提供的方法:Invoke 函式。

  • Invoke 方法介紹

Invoke 方法類似於 java 中的反射機制,它可以在執行時而不是編譯時呼叫函式。通俗地說,在 RFT 中,它可以根據字串來呼叫相應的函式。這使得不僅可以呼叫某些確定的方法(如 GuiTestObject 的方法),還可以主動查詢定製控制元件本身提供的方法,大大加強了物件識別能力。

  • 典型應用

使用 Invoke 函式的一個典型例子就是測試 Notes 8 的 tab 項。Notes 8 的 tab 項是一個定製的 java 控制元件。RFT 會將多個 tab 項識別為一個 GuiTestObject 物件,如何識別出每一個 tab 項呢?並執行關閉 tab 項的操作呢?

首先採用 Object map 方法識別出 RFT 能夠識別出的最小的定製控制元件的集合。如下圖 2 紅色方框所示的 GUI 元素是 RFT 所能識別出的最小的物件。在本例中它被識別為 GuiTestObject 的物件:sTabFolderObject。

圖 5 Notes 8 中定製控制元件

確定需要呼叫的方法。呼叫 Invoke 方法需要事先知道方法的名稱,TestObject 提供了另外一個方法:getMethods 它能夠返回控制元件所有的方法,你可以按照如下的方式呼叫它。


清單 6

按照這種方式,能夠在控制檯列印該控制元件所有可用的方法,從中分析出需要的方法。在本例中發現 getItems 能夠返回所有的 tab 項。

呼叫 Invoke 方法識別出具體的定製控制元件。完整的用法如下所示,引數 name 表示希望識別的 tab 項的文字值,sTabFolderObject 為上述紅色方框表示的物件。


清單 7

完成關閉 tab 項操作。利用 Invoke 可以很便捷的操作 GUI 物件,但是一定要避免使用使用者所不能操作的方式來操作控制元件,因為這違背了測試的原則。從 getMethods 返回的方法中發現 dispose 方法也可以關閉 tab 項,但很顯然使用者不能這樣操作,而使用者關閉 tab 項的操作就是點選 tab 項的“X”。因此在 RFT 指令碼中,可以首先得到“X”的座標,然後在該點執行單擊操作。具體的方法如下所示。


清單 8

  • 問題描述

使用 RFT 進行自動化測試時,經常遇到這樣的尷尬,一方面 RFT 在識別某些物件時遇到一些問題,比如無法識別,識別效率低,開發識別指令碼代價很高。另一方面又有大量的第三方 GUI 自動化工具對某些特定的領域有很好的效能。如果能夠結合 RFT 與其他自動化工具,就能夠極大地提高自動化測試的效率,更加適應敏捷開發與測試。

  • AutoIt 介紹

AutoIt 是一種在 windows 平臺上,針對 C/C++ 以及 windows 標準控制元件的,免費、開源的自動化管理工具。AutoIt 本身有一種非常簡單的指令碼語言,這種指令碼語言類於 Basic,並且其指令碼可以直接轉化為可執行程式且不依賴於任何庫。事實上,AutoIt 的這些功能,RFT 提供的 IWindow 介面也能夠完成,但 AutoIt 具有更高的效率。

  • 典型應用一

仍然以 IWindow 介面中點選“頁面設定”對話方塊中的“確定”按鈕為例。介紹如何結合 RFT 與 AutoIt 完成上述操作。

  1. 開發 AutoIt 指令碼。AutoIt 對 GUI 物件的識別區分 windows 和 controls。對於 windows 是通過 title/text 方式進行物件識別;對於 controls 是通過 title/text/controlID 方式進行識別。ControlID 是 AutoIt 中特有的概念,它不是一個特定的值,可以是:內部 ID,text,class,instance,classmn 以及它們的組合。在本例中,最終需要識別的物件是“確定”按鈕,同時它又位於“頁面設定”窗體中。具體的 AutoIt 指令碼如下。

  1. 在 RFT 中呼叫 AutoIt 指令碼。RFT 提供了多種啟動其它程序的方法,其中類 RationalTestScript 提供的 startApp 和 Run 方法比較常用。使用 startApp 需要事先在 IDE 中進行配置,而 Run 方法具有更多的普遍性,具體的呼叫方法如下。

清單 10

  • 典型應用二

在 RFT 中一類經常遇到的問題就是如何處理那些非預期的活動窗體。例如,點選安全網頁上的 link,而這個 link 所指向的卻是一個非安全的網頁,如果瀏覽器對安全性要求較高的話,就會彈出一個對話方塊詢問你是否仍然開啟這個頁面,如果選擇“是”則下次重複這樣的操作將不再會彈出對話方塊進行詢問,否則下次仍然會詢問。因此是否會出現這個窗體取決於是否建立了信任關係,而在指令碼開發時是無法預見的。

採用常用的物件識別技術,其典型的處理方法如下所示。

清單 11

上述處理方法採用了常用的物件識別技術識別那些非預期的窗體,如果這些窗體無法用常用方法識別,如何來處理這類問題呢?

圖 6 是開啟網頁前,系統彈出的一個對話方塊,它是一個 windows 原始窗體,無法採用常用方法識別(當然可以用 IWindow 來識別),以下結合 RFT 和 AutoIt 來處理。

  1. 開發 AutoIt 指令碼。AutoIt 指令碼的任務是點選“Security Alert”對話方塊中的“Yes”按鈕。這可以分為兩步,第一步判斷對話方塊是否已經存在;第二步點選“Yes”按鈕。具體的 AutoIt 指令碼如下所示。

清單 12

  1. 開發 RFT 指令碼。RFT 指令碼有三個任務,第一是點選安全網頁上的 link 使得“Security Alert”對話框出現。第二是呼叫 AutoIt 指令碼關閉彈出的對話方塊。第三是判斷非安全網頁是否已經開啟。具體的 RFT 指令碼如下所示。

清單 13

從以上可以看出,相比單純使用 RFT,基於 RFT 與 AutoIt 的混合解決方案需要的指令碼顯著減少,大大提高了指令碼開發效率。當然這種混合解決方案需要你對 AutoIt 有一定的瞭解,增加了學習的負擔,但是一旦掌握,對於提高自動化測試效率是很明顯的。

總結

本文闡述了各種不同的物件識別技術,其中 IWindow 介面用於識別 windows 標準控制元件;Invoke 方法用於識別應用程式定製的 GUI 控制元件;此外還介紹了 windows 平臺上一款優秀的自動化工具 AutoIt 以及如何與 RFT 結合進行自動化測試。將 RFT 常用的物件識別技術與這些特定條件下的物件識別技術相結合,能夠使得 GUI 自動化測試更加敏捷。

轉載:http://www.ibm.com/developerworks/cn/rational/r-cn-extendsrftobj/index.html