VS2010測試功能之旅:編碼的UI測試(3)-操作對象的識別原理

作者: RealDigit  來源: 博客園  發布時間: 2011-03-06 21:43  閱讀: 1932 次  推薦: 0   原文鏈接   [收藏]  

  回顧 

  在之前的兩章分別介紹了一個簡單的示例操作動作的錄制原理通過修改UIMap.UItest文件控制操作動作代碼的生成。想必大家對編碼的UI測試操作動作的錄制應該有一定了解了,在UI操作中,操作動作總是離不開具體的操作對象,例如點擊,拖動,填寫值等操作,總是要對文本框,或者按鈕,窗體這些對象進行操作,不是憑空生成的。本章作為入門篇的最后一章,將會說明編碼的UI測試是如何識別這些對象的,并介紹UIMap.UItest文件是如何生成對象識別代碼。

  對象的識別原理

  之前我們錄制的時候,錄制生成器解析了我們的操作對象,并且為我們生成了對象識別代碼(也就是UIMap.UItest下<Map>節點的那部分),以便我們在回放的時候,能夠識別到我們要操作的是哪一個對象。

  在編碼的UI測試中,對象的識別主要是同時按以下三個方面進行。

  1. 按對象類別:對象屬于什么類別,例如是button還是textBox 。

  2. 按關鍵標識屬性:能唯一識別該對象的屬性 。

  3. 按層級關系:對象在其父對象中的層次 。

  下面開始進行詳細介紹: 

  一、按對象類別:  

  為便于理解,以web程序為例,假設我們的識別代碼中,寫明讓VS2010按WebButton識別一個對象,那么VS2010則會在頁面源碼中只找到那些html標簽是<input type=“submit”>的控件,如果識別代碼中描寫的是按WebLink識別對象,則VS2010只在頁面源碼中找到那些是<a>的標簽。 

  二、按關鍵標識屬性:

  通過對象類別,已經能識別出來某一類的對象,在這個基礎上,接下來就需要用關鍵識別屬性進行精準標識了,我們需要找出能唯一識別該對象的屬性,假如一個窗體如下。

  這個窗體中包含了3個button,我們想讓VS2010操作到第一個Button,如何區分這些Button呢?這就要用到關鍵標識屬性來標識唯一一個對象。

  關鍵標識屬性分為兩種----自身標識屬性和輔助標識屬性。 

  1、自身標識屬性: 

  也就是屬于對象的屬性,例如,button擁有Name,Text,Enable,BackColor等屬性,我們假設上面那個窗體的Button的各個屬性如下。

  很明顯可以發現,第一個button的Name屬性和和其他的button不一樣,那么可以用其作為他的關鍵標識屬性,并且寫在識別代碼中,這樣vs2010就可以在這些button中能唯一識別他,例如,將Name=button2寫到識別代碼中,就可以唯一識別第二個Button。

  假設3個button的Name一樣,而BackColor不同,也可以用BackColor作為關鍵標識屬性。

  2、輔助標識屬性:

  在自動化測試中,還有一種屬性叫做輔助標識屬性,他并不屬于對象的屬性,但可以輔助標識對象。

  假設剛才那個窗體的各button屬性如下:

  可以發現他們的自身屬性都是一模一樣的,那么怎么做才能讓VS2010識別他呢?仔細觀察可以發現這樣一個情況。

  我們可以通過該對象是第幾個對象這樣的輔助屬性進行標識他。

  比如如果要識別第3個Button,則需要在識別代碼中設置其輔助標識屬性“對象序號”為3。

  三、按層級關系:

  雖然上面確定了唯一對象,的確已經可以標識出對象了,不過實際上在識別的時候還會按層級關系查找,例如第一章提到的一個簡單的窗體。

  我們用錄制生成器解析他的第一個文本框Tbx_uid,在自動生成的識別代碼中,他們的層級關系是這樣的。

  對應到剛才的Form,層級為:

  VS2010在識別這個Textbox1的時候,會只識別屬于 系統登錄Window下的Tbx_uidWindow下的Tbx_uid文本框。

  (注:按照常規的理解,其實應該“系統登錄窗體”和“Tbx_uid文本框”只有兩個層級,也就是窗體下直接就是文本框,但是VS2010默認解析的時候,會把一個TextBox解析成兩個層級,分為TextBoxWindow和TextBoxEdit,結果本來應該總共只有兩級結果搞成了三級,如果仔細觀察可以發現其他控件也是這樣的,所以在這里糾結的朋友希望你們看到此段后能夠減輕些疑惑...)

  UIMap.UItest文件控制識別代碼的生成

  在第二章上部分已經提到,在UIMap.uitest文件中,對象的識別代碼的生成部分是放在<Maps>節點下的,點擊生成代碼后,會將其真正起作用的識別代碼生成到UIMap.designer.cs下,那么他們的代碼究竟是怎樣的呢?

以剛才那個窗體生成的代碼為例,我們要識別TextBox1,如果使用錄制生成器,把TextBox1填入到對象庫,我們來看看他生成的識別代碼(可以簡略看,下面會有說明)。

 
<Maps>
<UIMap Id="UIMap1">
<TopLevelWindows>
<TopLevelWindow ControlType="Window" Id="UI 系統登錄Window" FriendlyName="系統登錄" SpecialControlType="None" SessionId="199642">
<TechnologyName>MSAA</TechnologyName>
<WindowTitles>
<WindowTitle> 系統登錄</WindowTitle>
</WindowTitles>
<SearchConfigurations>
<SearchConfiguration>VisibleOnly</SearchConfiguration>
</SearchConfigurations>
<AndCondition Id="SearchCondition">
<PropertyCondition Name="Name"& gt;系統登錄</PropertyCondition>
<PropertyCondition Name="ClassName" Operator="Contains">WindowsForms10.Window</PropertyCondition>
<PropertyCondition Name="ControlType">Window</PropertyCondition>
</AndCondition>
<SupportLevel>0</SupportLevel>
<Descendants>
<UIObject ControlType="Window" Id="UITbx_uidWindow" FriendlyName="Tbx_uid" SpecialControlType="None">
<TechnologyName>MSAA</TechnologyName>
<WindowTitles>
<WindowTitle> 系統登錄</WindowTitle>
</WindowTitles>
<SearchConfigurations>
<SearchConfiguration>VisibleOnly</SearchConfiguration>
</SearchConfigurations>
<AndCondition Id="SearchCondition">
<PropertyCondition Name="ControlName">Tbx_uid</PropertyCondition>
<PropertyCondition Name="ControlType">Window</PropertyCondition>
</AndCondition>
<SupportLevel>0</SupportLevel>
<Descendants>
<UIObject ControlType="Edit" Id="UITbx_uidEdit" FriendlyName="Tbx_uid" SpecialControlType="None">
<TechnologyName>MSAA</TechnologyName>
<WindowTitles>
<WindowTitle> 系統登錄</WindowTitle>
</WindowTitles>
<SearchConfigurations>
<SearchConfiguration>VisibleOnly</SearchConfiguration>
</SearchConfigurations>
<AndCondition Id="SearchCondition">
<PropertyCondition Name="Name"& gt;密碼 :</PropertyCondition>
<PropertyCondition Name="ControlType">Edit</PropertyCondition>
</AndCondition>
<SupportLevel>0</SupportLevel>
<Descendants />
</UIObject>
</Descendants>
</UIObject>
</Descendants>
</TopLevelWindow>
</TopLevelWindows>
</UIMap>
</Maps>

  別看UIMap.uitest里為這些對象生成的了一大堆代碼,其實對象中真正管作用的屬性就ControlType,ID兩個:

  ID這個屬性表示調用對象在對象庫中的ID,例如在第二章下部分,編寫ExecuteActions的時候,描述對那個對象進行操作

  ControlType這個屬性用于描述按什么類別來識別對象,識別原理之一的對象類別就是用這個表示  

   而管作用的節點也就這么兩個:

  <AndCondition>這個節點表示識別條件,他的子節點為<PropertyCondition>,表示具體識別條件,識別原理之二的關鍵標識屬性就用這個表示

  <Descendants>這個節點用于存放這個對象的子對象,識別原理之三的層級關系就是用這個表示 。

  現在把上面自動生成的代碼優化一下,把不必要的代碼刪除,并加上注釋。然后再使用這段XML代碼在錄制生成器生成UIMap.designer.cs代碼:

 
<Maps>
<UIMap Id="UIMap1">
<TopLevelWindows>
<!-- 表示最高級別的窗體,屬性ControlType表示按類型“Window”類型識別對象,對應識別原理之一-->
<TopLevelWindow ControlType="Window" Id="UI 系統登錄Window">
<!--TechnologyName標簽沒有實際作用,但是刪除了會報錯,因此保留,之后的也是-->
<TechnologyName>MSAA</TechnologyName>
<AndCondition Id="SearchCondition">
<!-- 表示窗體的關鍵標識屬性,識別的時候尋找Name屬性為“系統登錄”的窗體,對應識別原理之二-->
<PropertyCondition Name="Name"& gt;系統登錄</PropertyCondition>
<!--表示窗體的關鍵標識屬性,識別的時候尋找ClassName屬性為“WindowsForms10.Window”的窗體-->
<PropertyCondition Name="ClassName" Operator="Contains">WindowsForms10.Window</PropertyCondition>
</AndCondition>
<!-- 表示窗體的子對象,對應識別原理之三-->
<Descendants>
<!--UI 對象,按類型“Window”類型識別-->
<UIObject ControlType="Window" Id="UITbx_uidWindow">
<TechnologyName>MSAA</TechnologyName>
<AndCondition Id="SearchCondition">
<!-- 關鍵標識屬性,ControlName屬性為“Tbx_uid”的對象-->
<PropertyCondition Name="ControlName">Tbx_uid</PropertyCondition>
</AndCondition>
<!-- 他的子對象-->
<Descendants>
<!--UI 對象,按類型“Edit”(文本框)類型識別-->
<UIObject ControlType="Edit" Id="UITbx_uidEdit">
<TechnologyName>MSAA</TechnologyName>
<AndCondition Id="SearchCondition">
<!-- 關鍵標識屬性,Name屬性為“密碼 :”-->
<PropertyCondition Name="Name"& gt;密碼 :</PropertyCondition>
</AndCondition>
<Descendants />
</UIObject>
</Descendants>
</UIObject>
</Descendants>
</TopLevelWindow>
</TopLevelWindows>
</UIMap>
</Maps>

  接下來使用錄制生成器生成UIMap.designer.cs代碼,可以看到代碼如下: 

 
[GeneratedCode("編碼的 UI 測試生成器", "10.0.30319.1")]
public class UI 系統登錄Window : WinWindow//這里的繼承于WinWindow,是根據剛才XML文件里的屬性 ControlType="Window"生成的,表示按Window識別,對應識別原理之一
{
public UI 系統登錄Window()
{

//這里是搜索條件,也就是關鍵識別屬性,根據XML 文件的AndCondition節點中的內容生成,對應識別原理之二
#region 搜索條件
this.SearchProperties[WinWindow.PropertyNames.Name] = " 系統登錄";
this.SearchProperties.Add(new PropertyExpression(WinWindow.PropertyNames.ClassName, "WindowsForms10.Window", PropertyExpressionOperator.Contains));
#endregion
}

// 這里是他的子對象,對應于XML文件的Descendants節點,對應識別原理之三
#region Properties
public UITbx_uidWindow UITbx_uidWindow
{

get
{
if ((this.mUITbx_uidWindow == null))
{

this.mUITbx_uidWindow = new UITbx_uidWindow(this);
}

return this.mUITbx_uidWindow;
}
}

#endregion

#region Fields
private UITbx_uidWindow mUITbx_uidWindow;
#endregion
}
[GeneratedCode(
" 編碼的 UI 測試生成器", "10.0.30319.1")]
public class UITbx_uidWindow : WinWindow// 這里的繼承于WinWindow,是根據剛才XML文件里的屬性ControlType="Window"生成的,表示按Window識別
{

public UITbx_uidWindow(UITestControl searchLimitContainer) :
base(searchLimitContainer)
{

// 這里是搜索條件,也就是關鍵識別屬性,根據XML文件的AndCondition節點中的內容生成
#region 搜索條件
this.SearchProperties[WinWindow.PropertyNames.ControlName] = "Tbx_uid";
#endregion
}
// 這里是他的子對象,對應于XML文件的Descendants節點
#region Properties
public WinEdit UITbx_uidEdit// 這里的類型為WinEdit,是根據剛才XML文件里的屬性ControlType生成的(ControlType="Edit")
{
get
{
if ((this.mUITbx_uidEdit == null))
{

this.mUITbx_uidEdit = new WinEdit(this);
// 這里是搜索條件,也就是關鍵識別屬性,根據XML文件的AndCondition節點中的內容生成
#region 搜索條件
this.mUITbx_uidEdit.SearchProperties[WinEdit.PropertyNames.Name] = " 密碼 :";
#endregion
}
return this.mUITbx_uidEdit;
}
}

#endregion

#region Fields
private WinEdit mUITbx_uidEdit;
#endregion
}

總結

  在本章介紹了VS2010的對象識別原理,想必大家對這個應該有所了解了吧?

  我曾今在用UI測試做項目的時候,經常會發現這樣那樣的對象不能用錄制生成器識別,這個時候怎么辦呢?了解了對象識別原理,就可以自己改XML文件來控制對象的識別,如果有想做這方面練習的朋友,可以留下你的郵箱,我這里正在編寫一個C# Winform小程序,這個程序上的所有控件都經過特殊處理,無法用錄制生成器識別,只有通過自己修改XML文件來控制它的識別,如果想試試自己的身手,別忘了留下郵箱哦~~

  到這里編碼的UI測試的入門篇就完結了,接下來會進入進階篇,以實際的例子描述如何對一個項目進行測試。

  附1:VS2010編碼的UI測試支持識別的對象  

平臺 支持級別
Windows Internet Explorer 7.0
Windows Internet Explorer 8.0
(包括 HTML 和 AJAX)
完全支持
Windows Internet Explorer 6.0 不支持
鑲邊OperaSafari 不支持
Silverlight 3.0 不支持
Flash/Java 不支持
Windows 窗體 2.0 及更高版本 完全支持
注意
完全支持 NetFx 控件,但并非支持所有第三方控件。
WPF 3.5 及更高版本 完全支持
注意
完全支持 NetFx 控件,但并非支持所有第三方控件。
Windows Win32 可適用于某些已知問題,但不正式支持
MFC 可適用于某些已知問題,但不正式支持
SharePoint 部分支持
Office 客戶端應用程序 不支持
Dynamics (Ax) 部分支持
SAP 不支持
Citrix/終端服務 部分支持

 

  注:Silverlight4 現在已支持,詳情見http://www.silverlightshow.net/news/Coded-UI-testing-for-Silverlight-4-now-available-.aspx

 

  園子里scottxu已有這方面研究,相關文章http://www.cnblogs.com/scottxu/archive/2011/02/28/1967112.html

[GeneratedCode("編碼的 UI 測試生成器", "10.0.30319.1")]
public class UI 系統登錄Window : WinWindow//這里的繼承于WinWindow,是根據剛才XML文件里的屬性 ControlType="Window"生成的,表示按Window識別,對應識別原理之一
 {

    public UI 系統登錄Window()
    {
        //這里是搜索條件,也就是關鍵識別屬性,根據XML 文件的AndCondition節點中的內容生成,對應識別原理之二
         #region 搜索條件
        this.SearchProperties[WinWindow.PropertyNames.Name] = " 系統登錄";
        this.SearchProperties.Add(new PropertyExpression(WinWindow.PropertyNames.ClassName, "WindowsForms10.Window", PropertyExpressionOperator.Contains));
        #endregion
    }

    // 這里是他的子對象,對應于XML文件的Descendants節點,對應識別原理之三
     #region Properties
    public UITbx_uidWindow UITbx_uidWindow
    {
        get
        {
            if ((this.mUITbx_uidWindow == null))
            {
                this.mUITbx_uidWindow = new UITbx_uidWindow(this);
            }
            return this.mUITbx_uidWindow;
        }
    }
    #endregion

    #region Fields
    private UITbx_uidWindow mUITbx_uidWindow;
    #endregion
}


[GeneratedCode(" 編碼的 UI 測試生成器", "10.0.30319.1")]
public class UITbx_uidWindow : WinWindow// 這里的繼承于WinWindow,是根據剛才XML文件里的屬性ControlType="Window"生成的,表示按Window識別
 {

    public UITbx_uidWindow(UITestControl searchLimitContainer) :
            base(searchLimitContainer)
    {
        // 這里是搜索條件,也就是關鍵識別屬性,根據XML文件的AndCondition節點中的內容生成
         #region 搜索條件
        this.SearchProperties[WinWindow.PropertyNames.ControlName] = "Tbx_uid";
        #endregion
    }
    // 這里是他的子對象,對應于XML文件的Descendants節點
     #region Properties
    public WinEdit UITbx_uidEdit// 這里的類型為WinEdit,是根據剛才XML文件里的屬性ControlType生成的(ControlType="Edit")
    {
        get
        {
            if ((this.mUITbx_uidEdit == null))
            {
                this.mUITbx_uidEdit = new WinEdit(this);
                // 這里是搜索條件,也就是關鍵識別屬性,根據XML文件的AndCondition節點中的內容生成
                #region 搜索條件
                this.mUITbx_uidEdit.SearchProperties[WinEdit.PropertyNames.Name] = " 密碼 :";
                #endregion
            }
            return this.mUITbx_uidEdit;
        }
    }
    #endregion

    #region Fields
    private WinEdit mUITbx_uidEdit;
    #endregion
}

 

0
0
 
標簽:VS2010 測試
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()