九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
WEB 自動化測試演示

WEB 自動化測試演示

博客文章都轉移的  http://www.gh-m.cz.cc  上面了,請去新地址查看所有文章^o^         

前段時間看了一下 生生不息原創(chuàng) 的《自己動手寫web自動化測試框架》,感覺很不錯,很值得學習一下,可是中間忙了,就暫停了,這幾天清閑下,繼續(xù)研究。終于走了一個遍,領悟了一下其中的原理,感覺對于簡單的WEB UI測試還是很不錯的,方便又便捷,嘿嘿,等下來根據(jù)這個編一個適合自己的winform版的,加到我的 要你命3000 中,恩恩??!

           下面貼上 生生不息 的原創(chuàng),以備收藏。不知道為什么 生生不息 沒有下文了,怎么息了呢,想繼續(xù)學習也沒辦法,只能借他的肩膀,自己學習了。

------------------------------------------------------------分割線---------------------------------------------------------------

自己動手寫Web自動化測試框架

28六2008 Filed under: 網海摘抄, 軟件測試 Author: LeandRo

1 - 概述

記得幾年前一本《自己動手寫操作系統(tǒng)》在全國的技術范圍內引起了學習操作系統(tǒng)的熱潮。我不才在這里使用這本書的大名,來分享一下我在寫Web自動化測試框架上面的一些經驗。

首先定義一下Web自動化測試框架:Web自動化測試框架是一個類庫,他可以幫助測試人員快速寫出Web自動化測試代碼,并幫助測試人員在自動化報錯的時候快速找到Bug。

目前市場上成熟的Web自動化測試框架有不少,很出名的是Watir,是用現(xiàn)在大名鼎鼎的Ruby寫成的,相對于Watir,有一個也很不錯的.net版本,就是WatiN,WatiN可以說是市面上可以找到的最好的C# Web自動化測試框架。微軟和其他的大公司也有自己的一些Web自動化測試框架,但是公布的并不多。

我這里將會使用C#,一步一步的寫出一個最簡單不過的自動化測試框架。這個框架的功能是基本可以測試簡單的沒有Ajax,沒有框架,沒有Windows對話框的一些網頁。而如何測試Ajax之類的網頁,我將會在其他的專題中寫出。

首先我們看使用的非托管的類庫。我們在這里將會使用兩個非托管類庫:mshtml.dll和Interop.SHDocVw.dll。 mshtml是微軟IE的核心類庫,下面是Wiki百科的解釋:

Trident (also known as MSHTML) is the name of the layout engine for the Microsoft Windows version of Internet Explorer. It was first introduced with the release of Internet Explorer version 4 in October 1997, has been steadily upgraded and remains in use today. For version 7 of Internet Explorer, Microsoft made significant changes to the Trident layout engine to improve compliance with web standards and add support for new technologies.

開發(fā)人員可以通過mshtml提供的接口,訪問到IE布局對象,從而達到對Web的控制和檢查。

另一個類庫Interop.SHDocVw.dll則提供了一個InternetExploer的接口,可以幫助我們操縱IE進程,并且進行一些簡單的如前進,后退等操作。

這兩個類庫如果裝了VS2005都可以找到。mshtml是IE自帶的,在項目中選擇添加引用,然后在.net標簽下面找到Microsoft.mshtml就可以找到了。而Interop.SHDocVw要復雜一點,添加引用中,選擇瀏覽標簽,然后在下面的路徑就可以找到:C:\Program Files\Microsoft Visual Studio 8\Application\PreEmptive Solutions\Dotfuscator Community Edition

下一次我們將會講解如何創(chuàng)建IE的實例,并且操縱IE。

2 - 打開和操縱IE

這一個部分我們來講用SHDocVw對IE進行操作。

接下來的幾篇文章我們都會以Console Application來向大家介紹Web自動化的一些基礎。

Notice 以下的代碼在VS2005上通過測試,相信在VS2005 express已經VS2008上也可以通過,不過在VS2003上可能要稍微修改。使用vs2003的朋友,建議大家使用VS2005 express

瀏覽器使用了IE7。 IE6以及更低版本并沒有做過試驗。

首先我們打開VS2005,建立一個Console Application項目:

新建一個命令行工程

接下來我們需要包含兩個引用了,就是mshtml和SHDocVw。關于這兩個dll的簡單介紹,請參見:自己動手寫Web自動化測試框架1 - 概述

包含mshtml引用

第二個SHDocVw一定要在下面這個路徑找:(C:\Program Files\Microsoft Visual Studio 8\Application\PreEmptive Solutions\Dotfuscator Community Edition)

包含SHDocVw

包含兩個類庫之后,我們就可以使用C#來對IE進行一些基本的操作了。

我們要添加幾個命名空間,來簡化我們下面的代碼:

  1. using System.Diagnostics;   //要用到進程來啟動IE窗口

  2. using System.Threading;     //使用Thread.Sleep來等待

  3. using SHDocVw;

  4. using mshtml;

除了mshtml和SHDocVw之外,我們還使用了其他的兩個命名空間,因為我們要使用System.Diagnostics.Process類啟動IE進程,并且獲取IE的進程信息,使用System.Threading.Thread的sleep()方法等待。

接下來,我們就可以寫入代碼了:

Console.WriteLine("Launching IE ...");

Process p = Process.Start("iexplore.exe","about:blank");

Thread.Sleep(3000);

第一步,我們要打開IE進程,這里使用了Process的Start靜態(tài)方法生成一個進程。很好理解,傳入了兩個參數(shù),一個是IE的exe文件名,也可以寫入完整地址;第二個參數(shù)是IE自己的參數(shù),表示要打開的鏈接地址,我們在這里使用一個空白頁面。

接下來的事情就是等待,等待IE進程啟動,這里為了讓大家更快的抓到本質,沒有使用很復雜的等待代碼,只是很機械的等待了3秒鐘,大家可以根據(jù)自己機器的狀況進行修改。

Notice 這里為了讓大家可以更好的理解,我插一點Process的講解,如果大家對上面的Process打開沒有任何問題的話,直接跳過往下就好了。這里Process.Start()方法其實有4個重載,我們使用了第三個重載函數(shù),也就是第一個輸入文件名,第二個輸入參數(shù),我們可以在運行命令行中打"iexplore about:blank"直接打開一個空的IE窗口,也可以打"iexplore http://www.colblog.net/"直接打開一個瀏覽到目標網站的IE窗口。

IE啟動了,我們接下來的事情就是把IE附加給SHDocVw.InternetExlporer以便我們可以進行接下來的操作。

  1. Console.WriteLine("Attaching to IE ...");

  2. InternetExplorer ie = null;

  3. if (p != null)

  4. {

  5.   SHDocVw.ShellWindows allBrowser = new ShellWindows();

  6.   if (allBrowser.Count != 0)

  7.   {

  8.     for (int i = 0; i < allBrowser.Count; i++)

  9.     {

  10.       InternetExplorer e = (InternetExplorer)allBrowser.Item(i);

  11.       if (e.HWND == (int)p.MainWindowHandle)

  12.       {

  13.         ie = e;

  14.         break;

  15.       }

  16.     }

  17.   }

  18. }

  19. else

  20. {

  21.   Console.WriteLine("Error: Can not Launch IE");

  22.   return;

  23. }

  24. if (ie == null)

  25. {

  26.   Console.WriteLine("Error: Can not attach to IE");

  27.   return;

  28. }

首先,我們先聲明了一個InternetExplorer的引用,這里設為空引用。他以后會存儲我們的IE實例,并且通過它,我們可以操縱IE進行一些操作。

然后我們判斷剛剛啟動的進程p是不是為空,如果為空,就報錯,說明不能啟動IE(Can not Launch IE)。如果不為空,就可以進行下面的操作了。

注意,這里我們用了比較特殊的方法來得到InternetExplorer實例,就是通過比較當前Windows中已經存在的進程編號,來找到剛剛啟動的IE實例,用allBrowser來獲取所有的Shell Windows,然后逐個和剛剛啟動的進程p的Handle號進行比較,如果相同,就說明是我們想要的進程,把他的InternetExplorer實例賦給我們ie。

最后我們判斷一下ie引用是否有了實例,因為剛剛的循環(huán)我們無法保證一定有實例被賦給ie,這里如果檢查失敗,就報錯返回。

通過上面的幾步,我們已經啟動并且拿到了InternetExplorer的實例,我們可以對這個實例進行一些操作了。舉個最簡單的例子就是瀏覽到某一個網頁,下面的代碼讓這個瀏覽器指向了我的博客地址:

  1. Console.WriteLine("Navigating ...");

  2. object o = null;

  3. ie.Navigate("www.colblog.net", ref o, ref o, ref o, ref o);

這里都很簡單,只有一個讓人費解的地方就是object o。因為ie.Navigate需要5個參數(shù),后面的4個是可選參數(shù),所以我們只需要象征性的傳入一個null就可以了,有一個同事問我為啥不直接傳null,還要申請一個object,其實原因就在于參數(shù)是ref的,必須有一個引用被傳進去才行。關于后面的四個參數(shù)的講解請看msdn上的講解。

運行一下就發(fā)現(xiàn),程序順利的打開一個IE窗口,并且鏈接到我的博客上

下面附上源代碼,不過需要登錄才可以拿到,各位多多包含。

下一次我們來了解得到網頁中的各個Element。

3 - 操縱Web控件

上面的兩次課程我們介紹了mshtml和SHDocVw的一些用途,以及如何打開并且附加到IE上,實現(xiàn)IE的宏觀上的控制。

這次我們將會用代碼找到我們想要的控件,然后對控件進行一些操作。

首先我們引入一個很好的IE控件:Internet Explorer Developer Toolbar,這個控件可以幫助我們方便的找到我們想要的控件的屬性。

安裝好這個控件之后,我們就可以方便的找到每一個控件的ID,或者其他屬性了,如下圖

IE Developer

注意,打開IE Developer Toolbar之后,要點選下面的鼠標按鈕,才可以用鼠標來選擇我們想要的控件。有了這個控件,我們就不用去查看源文件來找到我們想要的信息了。其他的功能這里不多說了。

接下來我們以百度的三個控件為例,分別告訴大家如何使用ID得到TextBox,如何點擊使用ID得到的Button,如何使用子控件縮小范圍的方法得到一個HyperLink。

首先我們修改上次的代碼,把IE指到百度去:

  1. Console.WriteLine("Navigating ...");

  2. object o = null;

  3. ie.Navigate("baidu.com", ref o, ref o, ref o, ref o);

  4. Thread.Sleep(2000);

代碼我們在 《【生生不息原創(chuàng)】自己動手寫Web自動化測試框架2 - 打開和操縱IE》 都講解過了。只有一點,我們在完成IE的跳轉之后,等待了2秒鐘的時間,原因是IE的工作是需要時間的,我們在后面的測試框架部分會講解如何判斷IE已經完成了頁面的跳轉,在這里為了讓大家更好的了解我們本節(jié)的主題,只是用了簡單的等待。

然后我們用IE Developer Tools得到了關鍵字文本框的ID是kw,所以我們用下面的代碼在關鍵字文本框里面輸入了我們想要的關鍵字:

//得到一個Text Box

Console.WriteLine("Inputing Keyword ...");

HTMLDocument doc = (HTMLDocument)ie.Document;

HTMLInputElement keyword = (HTMLInputElement)doc.getElementById("kw");

keyword.value = "colblog.net";

Thread.Sleep(1000);

首先我們用ie.Document對象得到了HTMLDocument。目的沒什么可說的,因為我們需要HTMLDocument得到下面的控件。而這里之所以使用強制類型轉換,是因為Document對象在這里返回一個object的引用,但其實是一個HTMLDocument的實例。所以轉換一下就好了,在mshtml里面,這種情況還不少,在msdn上有詳細的講解,使用的時候查一下就好了。

然后使用HTMLDocument.getElementById方法,直接從Document里面按照ID取出想要的控件,返回一個IHTMLElement,IHTMLElement是HTMLElement的抽象,所有的HTML的tag都可以是一個IHTMLElement,返回這樣的一個引用,我們在知道將會返回什么類型的情況下,可以使用強制類型轉換來把對象轉成我們想要的引用。就像上面我們所做的,返回的其實是一個Input tag,所以我們要把他轉換成HTMLInputElement就好了。

下面一句我們直接對這個對象的value進行設置,就可以完成在關鍵詞文本框里面輸入我們想要的關鍵詞的動作。

接下來我們要點擊搜索按鈕:

  1. //得到一個按鈕

  2. Console.WriteLine("Clicking Submit ...");

  3. HTMLInputElement submit = (HTMLInputElement)doc.getElementById("sb");

  4. submit.click();

  5. Thread.Sleep(2000);

有了上面文本框的解釋,這一段代碼就容易多了吧。這里不在贅述。

聰明的讀者一定會問:我們現(xiàn)在使用ID查詢控件,如果我們的控件沒有ID怎么辦?如果ID是重復的怎么辦?

上面的兩種情況都是完全可能的,而且在實際中幾乎占據(jù)了大部分的情況。(不過ASP.NET里面的控件倒是都有ID,使用這種方法比較方便。)我們下面的例子就是去點擊百度首頁右上角的登錄超級鏈接。

首先我們分析一下,登錄超級鏈接是放在一個id為u的div里面,而登錄超級鏈接是沒有ID的。我們的思路就是先找到這個id為u的div,然后找他的chidren找到我們想要的這個超級鏈接,下面是源代碼:

  1. //得到一個鏈接

  2. Console.WriteLine("Clicking Login Button ...");

  3. IHTMLElement userPanel = doc.getElementById("u");

  4. IHTMLElementCollection HyperLinks = ((IHTMLElement2)userPanel).getElementsByTagName("a");

  5. IHTMLElement login = (IHTMLElement)HyperLinks.item(null, 0);

  6. login.click();

首先我們得到了那個id為u的div,命名為userPanel。這一步和上面沒啥區(qū)別。

下面一個語句我們得到了userPanel的控件的所有tag為a的控件,也就是所有的超級鏈接。這里有一個小小的需要注意的地方,我們看到這個語句吧IHTMLElement對象強制類型轉換成了IHTMLElement2,很有意思,為啥會這樣呢?其實IHTMLElement有4個這樣的兄弟,他們之間的方法不同,可以互相轉換,我們想要的getElementsByTagName在IHTMLElement2下面,所以我們就強制類型轉換到IHTMLElement2。這個方法返回一個IHTMLCollection。我們用HyperLinks來儲存這個引用。

因為userPanel的子控件只有登錄超級鏈接這一個,所以我們直接使用index為0來取道這個對象就好了。IHTMLElementCollection里面的item方法詳見msdn,我們只需要把第二個index設置為0,就可以取到第一個子對象。下面附上源代碼。

4 - 驗證Web控件

上次我們講到了如何控制Web控件,有了上次的基礎,我們這一次的東西就會比較簡單:如何驗證Web控。

我們知道我們測試的目的就是判斷被測產品是不是符合要求,如果是手動的測試,就是點到我們要判斷的地方,然后用眼睛去判斷出現(xiàn)的東西是不是我們想要的。

而自動化就稍微復雜一點。我們需要解決兩大問題:一個是操縱電腦去點擊,另一個就是去檢查是不是我們想要的結果。我們前面的文章可以解決操縱瀏覽器進行瀏覽,而接下來我們講的就是如何判斷是否正確了。

不考慮性能測試的話,檢查點無非有這么幾個:

內容是否正確

樣式是否正確

下面我們以實際代碼來講解如何判斷。

首先判斷一下樣式,我們接著上次的代碼,判斷一下百度首頁的文本框的大小是不是我們想要的(這個代碼接著上次的得到keyword控件之后,Submit之前):

  1. //驗證

  2. if (keyword.getAttribute("size", 0).ToString().Equals("36"))

  3.   Console.WriteLine("Validation Passed! Size is Correct");

  4. else

  5.   Console.WriteLine("Validation Failed! Size is wrong");

我們可以看到IHTMLElement有getAttribute方法,這個方法可以得到一個Element里面的Attribute,比如value,type,以及css樣式之類的,都可以用這個方法得到,見msdn對這個方法的更詳細的講解。

我們用下面的代碼對百度的搜索結果的內容和標題進行判斷:

  1. //驗證

  2. if(string.Equals(doc.title.Trim(),"百度搜索_colblog.net"))

  3.   Console.WriteLine("Validation Passed! Title is Corrected");

  4. else

  5.   Console.WriteLine("Validation Failed! Title is wrong");

  6. if (doc.body.innerText.Contains("生生不息"))

  7.   Console.WriteLine("Validation Passed! Body contains your string");

  8. else

  9.   Console.WriteLine("Validation Failed! Body do not contain");

IE的標題就直接用HtmlDocument的title屬性就好,而判斷字符就是用到了IHTMLElement的innerText屬性,這個屬性是我們很常用的屬性之一,他會將該Element中顯示在IE的字符串返回給我們,另一個相對應的屬性就是InnerHtml屬性,這個屬性會把這個Element里的所有html代碼返回。

比如說一個簡單的Dropdownlist,用InnerText就會返回這個List里面每一項的text,而使用InnerHtml就會返回這個list里面的html代碼。

在這里我們使用innerText來判斷是否有我們想要的文字在里面。

Notice 注意:innerText和innerHtml屬性,是IHTMLELement的屬性,所以我們得到的每一個IHTMLElement都可以拿到這樣的屬性,并不是只有body才可以。這樣我們以后就可以用前面的知識得到想要的IHTMLElement元素,然后再使用InnerHtml和InnerText來判斷內容。

除了這兩個,還有outerHtml和outerText可以使用。

這次的內容比較簡單。有的網友問到了一些比較實際的問題,比如如何判斷IE是否完成了頁面讀取,這里預告一下,在我的下一篇博客里,就會提到這個問題。敬請關注。

5 - 判斷瀏覽器是否加載完成

上面的幾次課程中,我們介紹了如何打開瀏覽器,如何獲取每個web控件的信息,并且控制并驗證他們。

從上面的文章中,我相信大家已經可以寫出簡單的測試程序了。但是還有一個很重要的問題沒有解決:如何判斷瀏覽器是否加載完成?

前面的文章我們沒有對瀏覽器的加載進行判斷,而只是簡簡單單的等一段時間,這不是一個很好的解決方法,一方面浪費了時間,另一方面,我們也無法知道應該等多久,導致我們的測試程序不夠穩(wěn)定。

接下來我們假設被測網頁沒有Ajax和框架,以這種情況來分析如何判斷網頁加載完畢。

現(xiàn)在比較常用判斷是否加載的方法有三種:

不停判斷IE的狀態(tài),如果沒有準備好就等待。

實現(xiàn)IE的DocumentComplete事件,標志完成。

不停去查找頁面有沒有我們想要控件,沒有就等待。

第一種方法:不停判斷IE的狀態(tài),我們要判斷IE的哪些狀態(tài)呢?

一方面,我們需要判斷IE的Busy狀態(tài),看IE是不是在忙著解析東西,另一方面判斷IE的ReadyState狀態(tài),看html文檔是不是被完全加載進來。

  1. while (ie.Busy || ie.ReadyState != tagREADYSTATE.READYSTATE_COMPLETE)

  2. {

  3.   Thread.Sleep(100);

  4. }

用如上的代碼就可以等待IE到完成。

Notice 這里只是簡簡單單的Demo,所以用了很簡單的預計進行判斷,我們假設我們的網頁沒有Ajax,也不會出現(xiàn)Load的死鎖,真正的實際工作要比這個復雜一些,比如要定一個Time out,如果除了Timeout的范圍,就強行終止,以防止測試過程中的死鎖。

而如何判斷Ajax是否被加載完,不是我們這個系列的討論范圍,請關注以后的其他系列文章。

這種方法是我比較推薦的一種方法,雖然《.net軟件測試自動化之道》推薦的是第二種方法,不過我經過實際的測試,推薦第一種方法。這個方法可以比較好的處理Navigate、Submit等情況,也是WatiN使用的方法(WatiN的用法要復雜很多,考慮到了Frame等其他情況)。

第二種方法:通過綁定DocumentComplete,用AutoResetEvent來等待。

InternetExplorer給我們提供了DocumentComplete事件,會在IE被Load之后被調用,我們可以使用這個來等待。等待方法就是使用System.Threading.AutoResetEvent對象來。

所以我們需要做的是:

聲明一個AutoResetEvent對象的實例,因為要在兩個方法直接調用,所以需要放到類的成員變量。

在InternatExplorer被獲取之后,綁定DocumentComplete事件。

在DocumentComplete事件中,調用AutoResetEvent.set()方法。

在等待頁面加載的時候調用AutoResetEvent.WaitOne()方法

下面是源代碼:

  1. //1.聲明AutoResetEvent對象實例

  2. private static AutoResetEvent DocComplete = new AutoResetEvent(false);

  3. static void Main(string[] args)

  4. {

  5.   //...省略得到IE對象

  6.   //2.綁定DocumentComplete事件

  7.   ie.DocumentComplete +=

  8.     new DWebBrowserEvents2_DocumentCompleteEventHandler(ie_DocumentComplete);

  9.   Console.WriteLine("Navigating ...");

  10.   object o = null;

  11.   ie.Navigate("http://www.baidu.com/", ref o, ref o, ref o, ref o);

  12.   //調用WaitOne等待

  13.   DocComplete.WaitOne();

  14.   HTMLDocument doc = (HTMLDocument)ie.Document;

  15.   HTMLInputElement keyword = (HTMLInputElement)doc.getElementById("kw");

  16.   keyword.value = "colblog.net";

  17.   HTMLButtonElement submit = (HTMLButtonElement)doc.getElementById("sb");

  18.   submit.click();

  19.   //調用WaitOne等待

  20.   DocComplete.WaitOne();

  21.   ie.Quit();

  22. }

  23. //實現(xiàn)DocumentComplete事件,調用Set方法。

  24. static void ie_DocumentComplete(object pDisp, ref object URL)

  25. {

  26.   DocComplete.Set();

  27. }

省略了一些前幾篇文章的東西,完整代碼請下載源代碼。

這種方法有自己的好處,就是使用了IE自己的事件,判斷代碼很簡單,不過有也不好的地方,第一就是幫度DocumentComplete事件以后,打開的IE會變得響應很慢,尤其是當設置斷點調試的時候,IE會變得尤其的慢。第二個缺點就是如果加上框架,還有頁面的跳轉,就會是這個方法很難捉摸。比如,如果上面的例子里面,URL寫成"baidu.cn",就會出錯。

第三種方法是不停的去讀我們要的控件是否出來。這個方法一般需要配合前面兩個使用,而且也可以部分解決Ajax的問題。因為具體實現(xiàn)代碼比較多,而又不是我們要講的重點,就不貼出源代碼,只是講一下實現(xiàn)的思路,讓大家了解一下。

具體實踐方法是:設置一個Timeout,在這個Timeout時間之前,不停的去看我們要驗證的控件是不是被Load進來。如果對頁面進行建模,就會去看我們的這個頁面的所有的已經定義了的控件是不是被Load進來,如果出了Timeout,就會報錯。

這個方法的優(yōu)點是可以部分解決Ajax,但是缺點也就是實現(xiàn)比較復雜,而且如果報錯,無法分清是因為頁面沒有這個控件,還是因為速度較慢,控件還沒有被讀入。

以上介紹了在沒有Ajax和框架情況下,如何判斷瀏覽器是否已經加載完成。從下一篇文章開始,我們就要進入正題,開始我們的自動化測試框架了。

6 - 自動化測試框架的規(guī)劃

從今天開始,我們正式進入自動化測試框架的編寫中。

首先我們先進行需求分析:我們到底要什么樣的自動化測試框架?

正如第一篇《【生生不息原創(chuàng)】自己動手寫Web自動化測試框架1 - 概述》中提到的,我們要做的是一個簡單的自動化測試框架,沒有Ajax,沒有框架,沒有Windows對話框,我們舍棄這些較為復雜的功能,目的就在于,我們想要把注意力集中在自動化測試框架的架構上,以后我們可以慢慢加入這些功能,但是第一次,我們不要。

這里規(guī)劃一下,我們想要的自動化測試框架是什么樣子的,那么要從我們的自動化測試說起了。自動化測試代碼一般是在什么時候寫的呢?在微軟里,自動化測試代碼應該和被測試的網站的代碼同步開發(fā),因為有了Spec(Specification),我們就可以根據(jù)Spec來測試用例,然后把我們認為重要的,必須經常重復的用例自動化起來。

但是問題在于,我們在沒有網站的情況下,如何進行自動化測試的開發(fā)呢?我們面臨的困難主要有以下的方面:

沒有網站,就沒有網頁元素的ID之類的標識,沒有辦法按照上面的辦法獲取我們想要的網頁元素。

網站建設初期,頁面元素不穩(wěn)定,一個小小的ID的變更就可以使我們的自動化代碼變的無用。

即使是頁面元素不變,一個小小的業(yè)務邏輯的改變,也可能會很大的影響到我們的自動化測試代碼。

我們的自動化測試框架,一定要可以比較好的解決上面的問題。

我想很多的讀者已經明白了,我們要做的就是把網頁的元素和網站的業(yè)務邏輯分開,這樣就可以比較好的解決這些問題。

我們最終的目標是在一個類里面去定義整個網站的架構,比如這個網頁上有一個文本框,有幾個按鈕。就像下面的這段代碼

  1. public class Baidu

  2. {

  3.   WebBrowser wb = new WebBrowser("www.baidu.com");

  4.   private Button submit;

  5.   private TextBox keyword;

  6.   public Button Submit

  7.   {

  8.     get{

  9.       if (submit == null)

  10.       {

  11.         submit = new Button(wb, "sb");

  12.       }

  13.       return submit;

  14.     }

  15.   }

  16.   public TextBox Keyword

  17.   {

  18.     get

  19.     {

  20.       if (keyword == null)

  21.       {

  22.         keyword = new TextBox(wb, "kw");

  23.       }

  24.       return keyword;

  25.     }

  26.   }

  27. }

上面的代碼,我們定義了兩個屬性,一個是Button Submit,另一個是Textbox Keyword。這兩個屬性定義了百度首頁的兩個最重要的元素,我們也可以定義更多的比如登錄的HyperLink或者其他的一些元素,但是我們現(xiàn)在以這個為例子來定義。

Notice 這里的代碼定義并不是最簡單的,讀者完全可以通過自己的努力對測試框架進行修改,把這個代碼做到更簡單,不過我們這里以這個代碼為例,來講述自動化測試框架的架構等比較高層的東西。我們可以以后來細化這里。

經過以上的定義,我們的業(yè)務邏輯代碼就可以被簡略到如下的語句:

Baidu b = new Baidu();

b.Keyword.Text = "生生不息";

b.Submit.Click();

這里我想很簡單,就是我們打開一個百度的實例,然后輸入生生不息,然后點搜索按鈕。我們以后還可以更多的建模,把驗證也放在里面。

怎么樣?如果我們的的自動化測試框架可以達到這樣的效果,我們就可以很好的解決上面提出的問題,當Web的開發(fā)還沒有完全成型的時候,我們可以定義頁面的元素,空著ID不填,然后把業(yè)務邏輯做好,一旦Web開發(fā)完成,我們只需要填補上網頁元素的定義,自動化測試代碼就可以完成。

是不是已經摩拳擦掌了?我們從下一節(jié)開始,自動動手來做出這樣一個自動化的測試框架來。

7 - 框架架構的設計

上次我們分析了什么是我們想要的自動化測試框架,這一次我們基于上一次的分析,來設計我們的自動化測試框架架構。

首先,我們需要一個類,去做幫助我們處理和IE相關的事情,幫助我們操縱IE,打開和關閉IE。然后,我們需要一組的類,來描述網頁上的元素,比如TextBox和Button,去模擬他們的事件,去取得他們的狀態(tài)??傮w來說就是封裝這些元素。

除此之外,我們還需要一些輔助的類來幫助我們做一些工作。

接下來我們就先去分析幫助我們操縱IE的類應該有那些功能。所以我們把這個類命名為WebBrowser。參考附帶的WebBrowser.cs文件。

首先,我們需要一些內部的成員和輔助類,我們打開的IE進程會用SHDocVw.InternetExplorer類來接受,我們可以把這個變量存在整個類的私有變量去。還有我們其實要取出的是這個網頁的HTMLDocument類,以供以后來使用。這里我們直接寫成了internal,成員變量,其實可以封裝成一個屬性,看大家的用法了。除了這些,我們還需要一個Timer類,這個類幫助我們完成一些計時的工作。見附帶的timer.cs文件。

其次,打開IE進程這樣的事情應該是由這個類來做的,由于這次對WebBrowser的要求不高,我就在構造函數(shù)里面講IE進程初始化好,具體如何處理這些請參見《【生生不息原創(chuàng)】自己動手寫Web自動化測試框架2 - 打開和操縱IE》。我們給這個類構造函數(shù)提供了一個帶有string參數(shù)的方法,目的是讓用戶可以方便的傳入URL而打開瀏覽器并且轉到我們要的頁面去。當我們沒有參數(shù)給構造函數(shù)時,用戶就會得到一個空的頁面。

再次,我們需要一個NavigateTo函數(shù),來操縱瀏覽器轉到某一個地方去。這個函數(shù)不多說,就是我們以前的內容。

最后,我們在這里添加了一個DoWait的函數(shù),這個函數(shù)的主要目的是完成我們《【生生不息原創(chuàng)】自己動手寫Web自動化測試框架5 - 判斷瀏覽器是否加載完成》里面所討論的等待瀏覽器加載完成。DoWait放在這里的原因是我們需要在幾個地方判斷頁面加載完成:瀏覽器瀏覽到了新的頁面、用戶點擊了某些按鈕或者鏈接、或者甚至用戶改變了控件的狀態(tài),導致頁面回刷,這幾個地方會分別被WebBrowser和以后的Web控件類所使用,所以我們把這個DoWait放在WebBrowser里面,以后的Web控件回去引用WebBrowser類的這個方法來判斷瀏覽器是否完成加載。

Notice 注意,這里把DoWait的代碼寫在WebBrowser里面是基于我們以上的頁面沒有Ajax和框架的假設做出的,如果頁面可能有Ajax,我們就不可能簡簡單單的用這個DoWait去等待加載完成。

我們以后會有對目前框架的改進文章,這些文章會討論這些問題。

這樣我們的WebBrowser就大概寫完了。下一次我們會講解一組類來實現(xiàn)Web控件。

------------------------------------------------------------分割線---------------------------------------------------------------

下面貼上我測試用的源代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using SHDocVw;
using mshtml;

namespace kj01
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Launching IE ...");
            Process p = Process.Start("iexplore.exe", "about:blank");
            Thread.Sleep(3000);
            Console.WriteLine("Attaching to IE ...");
            InternetExplorer ie = null;
            if (p != null)
            {
                SHDocVw.ShellWindows allBrowser = new ShellWindows();
                if (allBrowser.Count != 0)
                {
                    for (int i = 0; i < allBrowser.Count; i++)
                    {
                        InternetExplorer e = (InternetExplorer)allBrowser.Item(i);
                        if (e.HWND == (int)p.MainWindowHandle)
                        {
                            ie = e;
                            break;
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("Error: Can not Launch IE");
                return;
            }
            if (ie == null)
            {
                Console.WriteLine("Error: Can not attach to IE");
                return;
            }
            Console.WriteLine("Navigating ...");
            object o = null;
            ie.Navigate("            Thread.Sleep(2000);
            //得到一個Text Box
            Console.WriteLine("Inputing Keyword ...");
            HTMLDocument doc = (HTMLDocument)ie.Document;
            HTMLInputElement keyword = (HTMLInputElement)doc.getElementById("kw");
            keyword.value = "天津";
            Thread.Sleep(1000);
            //驗證
            if (keyword.getAttribute("size", 0).ToString().Equals("36"))
                Console.WriteLine("Validation Passed! Size is Correct");
            else
                Console.WriteLine("Validation Failed! Size is wrong");
            //得到一個按鈕
            Console.WriteLine("Clicking Submit ...");
            HTMLInputElement submit = (HTMLInputElement)doc.getElementById("sb");
            submit.click();
            Thread.Sleep(2000);
            //驗證
            if (string.Equals(doc.title.Trim(), "百度搜索_天津"))
            {
                Console.WriteLine("Validation Passed! Title is Corrected");
                //Console.ReadLine;
            }
            else
                Console.WriteLine("Validation Failed! Title is wrong");
            if (doc.body.innerText.Contains("天津地圖"))
            {
                Console.WriteLine("Validation Passed! Body contains your string");
                Console.ReadLine();
            }
            else
                Console.WriteLine("Validation Failed! Body do not contain");
            ////得到一個鏈接
            //Console.WriteLine("Clicking Login Button ...");
            //IHTMLElement userPanel = doc.getElementById("u");
            //IHTMLElementCollection HyperLinks = ((IHTMLElement2)userPanel).getElementsByTagName("a");
            //IHTMLElement login = (IHTMLElement)HyperLinks.item(null, 0);
            //login.click();
        }
    }
}

打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Web 應用程序用戶界面低層測試自動化
Android自動化框架
自動化測試原理
VB.NET教程
UI自動化測試該怎么做?
C# 第一天代碼
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服