沈大框,黃永鋒,羅保國
1(東華大學 計算機科學與技術學院,上海 201620)
2(中國科學院 軟件研究所,北京 100190)
21世紀以來,隨著通信技術的飛速發展,互聯網行業市場份額所占比重越來越高.傳統落后而且效率低下的手工軟件測試已經不能滿足市場的需求,Web程序自動化測試技術越來越受人們的重視.這幾年,各種Web自動化測試工具被相繼推廣發行,已經得到廣泛的應用.但這些測試工具主要研究瀏覽器中Javascript的執行機制和它們對不同瀏覽器的兼容性.以此在原來的基礎上豐富庫函數,從而增加測試的功能和提高測試工具的穩定性.雖然這些測試工具功能全面,能夠讓繁瑣的任務自動化,節省人力資源,降低測試成本.但是近年的研究只是對測試工具的功能積木式的累加,并沒有實質的創新與突破.大多數測試工具依然需要借助傳統的編譯器才能執行測試.這需要使用者具備一定的編程能力,而且測試腳本開發成本較高.所以當下Web軟件自動化工具的發展依然讓測試具有很高的門檻[1–3].
目前,較為常見的Web自動化測試工具集主要包括 Ranorex、QTP、WinRunner、Selenium、Watir、Sahi等.前三者是商用的Web程序自動化測試工具,功能強大但價格昂貴.后三者是開源的Web程序自動化測試工具.雖然在使用上比不上商用所能提供便利的可視化效果和舒適的使用方式,但是已經能夠滿足測試人員的使用需求.而且Web應用不同于傳統的Window應用,Web產品具有產品數量大、產品變化快、對硬件環境和網絡敏感等特點.所以人們會去優先選用像Selenium這種兼容性較強的測試工具[4].
事實上,Selenium測試工具是歷史發展最為悠久、測試功能最為全面、腳本支持最多的測試框架.Selenium可以部署在Windows、Linux和macOS平臺上.它支持腳本的錄制與回放功能,通過Selenium IDE來錄制測試腳本,并提供UI編輯中間的任何步驟.錄制保存后可以后可以使用Selenium RC或者Selenium WebDriver來回放錄制內容.錄制的腳本被記錄在Selenese中,這是一種針對測試Web應用程序的Selenium命令集.但是它的命令集不具備編程語言的特性,只能處理簡單的測試單元.實際應用中,人們很少使用Selenese來編寫測試用例,而是使用Java,Python,Ruby等[5].
所以本文選擇以Selenium為切入點,從研究Selenium的測試機制出發,設計一個專用的Web自動化解釋器.該解釋器能實現測試腳本與測試數據的分離、自動生成測試報告和支持半自動化測試,從而提高Web自動化測試的柔性和實用性.通過分析Selenium WebDriver API中的測試功能來構建測試的類的依賴關系,把Selenium測試功能劃分成為一個層次分明和分工明確的結構體.然后根據Web應用程序自動化測試的流程和Selenium的測試功能的劃分對該解釋器構建模塊.從測試的需求出發,使能初步設計出一個以Selenium為后端,更加符合人們使用習慣的腳本解釋器.最終期望測試人員使用該解釋器能夠降低自動化測試的門檻和提高測試開發的效率.
Selenium升級到2.0以后,它重點發展了Selenium WebDriver.由之前的必須先啟動Selenium Server使其與各個瀏覽器進行通信交互發展到直接調用瀏覽器本身的WebDrive驅動進行與瀏覽器的會話,繞過JavaScript沙箱,提高了Selenium的測試效率和對各個瀏覽器的兼容性.圖1是Selenium的測試原理.新一代的Selenium做Web軟件自動化測試,本質上是調用Selenium API關于WebDriver的API.WebDriver是嵌入在瀏覽器中的驅動,能夠直接調用瀏覽器的原生JavaScript來控制瀏覽器,相當于模擬人類對瀏覽器的操作.如點擊某個位置、給某個輸入框輸入鍵值等.本章從Selenium WebDriver入手,著重分析WebDriver API接口的特點,先對Selenium測試進行模塊拆解,然后對解釋器進行模塊建立[6].

圖1 Selenium的測試原理
根據SeleniumAPI文檔,Selenium對瀏覽器的控制操作主要放在了RemoteWebDriver、RemoteWeb-Element、RemoteWindow和Actions這四個類中.前三個類分別表示瀏覽器、控件、和窗口層次的概念.瀏覽器位于最高層次,RemoteWebDriver類中的方法能夠對瀏覽器和窗口的特性進行控制,也可以對控件進行查找并創建控件對象.RemoteWebElement類里包含控件的屬性值和控件的動作,它自己也提供對控件的查找與創建.RemoteWindow類中包含窗口的屬性值和窗口的動作,但是它必須通過瀏覽器來創建并控制窗口的動作.圖2是三個測試類之間的依賴關系.Actions類對上述三個類測試功能的擴展,一方面它提供了模擬鼠標和鍵盤的一些動作以及組合鍵使用.另一方面Actions類既可以完成控件單一的動作,也可以把多個動作合成一個具有測試順序的組合動作.綜上所述,根據這幾個類提供的測試方法對其進行分類,可以把Selenium的測試分為5個模塊,分別為: 獲取控件屬性值,獲取窗口屬性值、控件定位、執行控件動作、執行窗口動作,這也是對應解釋器的初始模塊.

圖2 測試類之間的依賴關系圖
在Web自動化測試中,除了對瀏覽器的窗口與頁面進行模擬人類的操作.還需要去檢查頁面的屬性值是否和預設的結果一樣,以及觸發某一動作后,檢查一下該動作是否觸發成功.所以除了根據Selenium提供的API把解釋器構建成上述5個模塊以外,還需要根據實際的測試需求增加數據的驗證.上述5個模塊的測試都需要進行數據驗證,它們共同指向數據驗證模塊.如圖3是解釋器的模塊結構圖.SeleniumAPI中沒有對數據驗證提供相關的接口,需要測試開發人員使用它所依賴的程序語言人工編程實現.這也就給測試帶來很多額外的開發成本.從測試需求出發,在解釋器設計階段給解釋器增加數據驗證與檢查模塊.這樣能增加解釋器的可擴展性,降低測試腳本、測試數據和測試報告之間的耦合性.

圖3 解釋器的模塊結構圖
Selenium使用Java、Python、Ruby等編程語言編寫的測試腳本,一方面開發難度較高,另一方面可讀性較差.本文研究的基于Selenium的解釋器是專門針對測試的,避免了像Selenese那樣僅提供測試指令集,無法進行具有控制邏輯的測試.解釋器的基礎的語法參照Python和Octave等解釋器型的語法規則,刪除了與測試無關的部分,同時也根據測試的特點進行改進和增添新的測試使用方式.該解釋器仍包含一般編程語言具有的基本模塊如變量與常量、表達式、算術運算符、關系運算符、邏輯運算符、條件語句、循環語句、宏定義、內部函數與外部函數、輸入與輸出等.這使得解釋器能完成具有復雜邏輯的測試需求,同時簡化整個編譯器的語法,降低使用難度.
在測試的過程中,經常有獲取瀏覽器窗口與控件元素屬性值的需求.如獲取這些屬性值來驗證它們的正確性或者暫時保存下來給后續的測試步驟使用.窗口屬性值主要包括窗口的URL、窗口的標題、窗口的Handle、窗口的Body內容等.控件元素的屬性主要包括XY(橫縱)坐標、元素的標簽名、元素的屬性值、和元素的css屬性值等.如果用Java或Python的Selenium來獲取上述屬性值,則需先創建窗口或控件的對象,然后調用對象里的方法來實現,這需要測試人員有面向對象的編程思想,并且開發步驟繁瑣.參考Javascript的框架JQuery獲取元素對象的方法,Selenium解釋器可以使用$(string_name)來獲取窗口的屬性值,其中括號里的變量為窗口屬性的名稱.用$(*var)、$(.class)、$(:attr)等獲取控件元素的屬性值,其中var表示控件元素特定簡寫值如X、Y分別表示坐標;class表示控件元素的class屬性值; attr表示控件元素的Attribute屬性值.
Selenium在獲取當前頁面的控件元素時,通過篩選方法來得到控件對象.使用時需要調用FindElement(string type,string value)函數,它傳入了兩個參數: 定位方式和定位的屬性值.解釋器依照上述使用方式,把定位方式定義到腳本的語法層次.根據Web程序測試的特性,Selenium提供了8種控件查找方式,分別是Xpath、LinkText、Id、Tagname、ClassName、Name、PartialLinkText、CssSelector.為了提高控件抓取的效率,和抓取控件的多樣性、以及符合編程人員的使用習慣,解釋器參考JQuery和W3C對網頁的定義的標準,用@/xpath、@&LinkText、@#id、@ 執行動作包含兩類動作: 一是當前控件的動作,二是瀏覽器的窗口的動作.控件的動作包括點擊、文本框傳入鍵值、移動鼠標到指定位置等.瀏覽器的窗口動作包括打開某一版本的瀏覽器、切換窗口、導航窗口到指定鏈接、處理彈框等.執行動作時與函數的調用一樣,把動作執行看做內部函數的調用.直接使用函數名稱并傳入相應的參數來實現,比如OpenWindow(string url)表示當前瀏覽器打開一個指定URL的新窗口. Web軟件自動化測試要求在測試某個功能后,需要檢查該功能的正確性.即驗證當前頁面或者經過某次執行動作后頁面的一些屬性值與給定的參數值是否相等.驗證檢查需求有很多,如驗證窗口的URL、控件元素的標簽名、某個Select控件是否被選中等.使用Java或Python 的Selenium做Web自動化測試驗證,需要根據根據測試報告的格式定義數據結構,然后手工編程實現判斷驗證內容的正確性,最后把驗證結果寫入測試報告對象中,它們均不能自動生成測試報告.在解釋器層面先引入測試步驟的概念,并在它內部預先定義好通用的測試報告格式,這些測試報告可以用外部配置文件去修改,以便兼容其他平臺或公司內部測試報告格式.使用驗證表達式!($(url)==url)能夠直接完成上述驗證測試的需求,并把驗證結果寫入到測試報告[7]. 解釋器為了適應市場的需求,率先提出“半自動化測試”的思路,在適合自動化執行的地方嵌入機器代碼,在不適合于自動化的地方仍舊由人工進行.腳本中嵌入/1: message,解釋器遇到這行代碼會彈出提示信息,提示信息即腳本中的message.測試人員可以先手工測試一段難以實現自動化的步驟,并填寫是手工測試的完成情況,然后點擊彈框的確定按鈕,解釋器會繼續執行后續的測試.這種設計方案中,提供人工操作與機器代碼執行可隨時切換的功能,從而讓測試團隊在安排自動化測試的任務時更加靈活. 解釋器(英語: Interpreter),是一種計算機程序,能夠把高級編程語言逐行解釋運行.在本文設計的解釋器中,它先調用詞法分析器取得Token,每遇到一個終止符就調用語法分析器生成語法樹.然后調用已經封裝好的基于C#的Selenium特征庫,執行該語句.瀏覽器Web頁面會接收到解釋器發來的命令,處理相應的動作.總之解釋器的目標是努力向前按步執行下去,直到腳本程序執行結束[8–10].圖4是自動化測試解釋器流程圖. 為了證明該解釋器的功能性、測試腳本的簡易性和可閱讀性.專門設計一個登陸驗證的測試用例,然后使用本文設計的解釋器對測試用例進行腳本開發和測試執行.登陸驗證通過對登錄名和密碼的輸入框分別鍵值為空、鍵值錯誤信息、鍵值正確信息,一共9種情況,然后點擊登錄,驗證登錄結果與預先設定的結果是否一致.這9組數據全部測試通過,登錄驗證功能才能判斷為通過[11].登錄驗證的測試腳本和測試報告如下: 從上述測試腳本看出,幾乎每行測試腳本都能看到測試的影子,腳本具有極強的可讀性.十幾行代碼就實現一個完整的登錄驗證測試,并能自動生成測試報告.說明該解釋器語法的設計很適合進行Web自動化測試,測試開發很容易實現. 為了能綜合評價該解釋器的實用性,使用本文設計的解釋器與Selenium的Java、Python和Ruby版對上節登錄驗證的測試用例在9組登錄數據上進行了腳本開發,并執行測試.腳本開發過程中對開發難度做和測試數據與測試腳本分離難度做了評估.測試過程中,采集了測試用例的運行時間.最后綜合從開發難度、是否生成測試報告、是否支持半自動化測試、測試數據與測試腳本分離難度和運行時間5個維度綜合評價解釋器.其中運行時間能有效評估解釋器的執行效率.表1是Selenium測試的比較. 由此可見,本文設計的解釋器更加容易實現測試開發和測試數據和測試腳本的分離.并且解釋器增加了自動生成測試報告和支持半自動化測試的功能.一定程度上增強了該解釋器的實用性.由表中的運行時間數據,該解釋器在同一個測試用例上的運行時間少于Selenium的其他語言,得出該解釋器的執行效率也有所提升.總體來說本文設計的解釋器在Web自動化測試方面具有更高的實用性和優越性. 圖4 自動化測試解釋器流程圖 表1 Selenium測試的比較 本文從解釋器的研究出發優化了Selenium自動化測試,初步設計了一個專門用于Web自動化測試的解釋器.該解釋器的語法從測試角度出發,使得測試人員更加容易學習和使用.從實驗結果可以看出基于Selenium的解釋器可以降低測試人員的使用門檻,提升測試的效率,具有更高的使用價值.但當前解釋器對Web測試的語法還不夠精煉和完善,解釋器的穩定性和執行效率還有很大的提升空間.未來將會在這兩個方向去做更深入的研究.2.3 窗口與控件的動作執行模塊
2.4 驗證與檢查模塊
2.5 半自動化測試
2.6 解釋器執行過程
3 解釋器的測試與評價
3.1 解釋器的測試



3.2 解釋器的評價


4 總結與展望