朱佳藝,劉從軍
(江蘇科技大學 計算機學院,江蘇 鎮江 212003)
隨著信息技術的發展,Web 應用越來越流行,如今越來越多的軟件系統都是Web 應用程序,基于Web 的應用承載著越來越復雜的業務邏輯和越來越龐大的信息平臺結構,且發布周期短,更新迭代快[1],這就要求Web 應用程序測試具有全面性、可擴展性和高效性。承載Web 應用的瀏覽器具有多樣化和多元化的特征,因而增加了Web 應用測試的復雜性和工作量。因此,應該更多地關注Web 應用程序測試的效率、可重用性和全面性[2]。
軟件測試的目的是盡可能早地發現軟件中的缺陷。軟件測試的花費占整個軟件開發生命周期的30%~60%,具體取決于產品的關鍵性和復雜性。軟件測試是一個驗證軟件功能性和非功能性要求的過程,有助于基于軟件的功能性、可靠性、可用性、效率、可維護性和可移植性等屬性是否符合ISO-9126-1標準來控制產品質量[3]。
測試人員對Web 應用程序進行驗收測試通常采用手動測試的方法,而手動測試是個耗時的過程,而且需要人為的干預,容易出現人為錯誤,從而浪費時間。為解決這些問題,自動化測試應運而生。自動化測試是一個自動測試的過程,包括設計、執行測試腳本和使用高效的自動化工具。自動化測試可以提高軟件測試質量,使人為干預在軟件測試中占比最小化[4]。
常見的Web 自動化測試工具如QTP、Win Runner Load Runner、Robot、SilkTest、Selenium 等在自動化測試中得到了廣泛應用。Selenium 可以說是最全面、最流行的開源Web自動化測試工具[5],特別對使用了BackBase 框架的Web 應用程序提供了良好支持 。
大型軟件開發公司有相對成熟的測試技術,如Automated Testing Specialists Inc.提出數據驅動測試技術[6],Mercury Interactive Inc.推出關鍵字驅動測試技術[6]。文獻[7]采用Selenium 工具對某系統進行了完整的自動化測試,但所進行的研究只針對特定系統,腳本無法復用在其他系統上;文獻[8]設計一個基于Selenium 的自動化測試框架,并結合Jenkins、Pytest 等工具,具有穩定性、靈活性、可重用拓展、輕量級等特點,其采用數據驅動模式對難定位的元素進行二次處理,對驗證碼進行簡單識別;文獻[9]設計的基于Selenium 的自動化測試框架支持兼容性測試、日志記錄、頁面截圖、測試報告自動生成,但并沒有對驗證碼的識別進行處理,也沒有自動構建和部署測試的功能。
本文提出的基于Selenium 的自動化測試框架相比于文獻[7]-[9]的創新之處在于:框架可以復用,并不局限于某一系統;能部署在多臺機器上同時進行測試,既節省了時間,又測試了兼容性;對驗證碼的識別更簡單。實驗結果表明,該框架對于提升測試的可重用性、可擴展性、全面性、準確性具有較好效果。
測試人員首先分析軟件需求,根據需求設計測試用例。測試用例通過評審后,傳統會根據測試用例中描述的步驟流程對應用進行手工測試,然后將得到的真實結果與預期結果進行對比。因此,為了節省人力、物力、時間、資源等成本,提高測試效率與準確度,研究者提出了自動化測試的概念。自動化測試是指將人為手動執行的測試行為轉化為機器自動執行的過程[10]。
自動化測試有很多類型,比如功能的自動化測試、性能的自動化測試等。功能自動化測試是指借助自動化工具或框架來部署并執行測試腳本,從而自動化測試并驗證軟件功能[11];性能自動化測試是指通過工具或框架模擬成千上萬的用戶向系統發出請求,從而測試系統的處理能力、負載能力、穩定性與吞吐量等[12]。
自動化測試的項目大多滿足以下3 個條件:①軟件需求穩定。如果軟件需求經常修改,或者變動跨度較大,則需要修改測試用例,并修改測試腳本,導致維護、測試腳本的成本可能高于節省的測試成本,與當初的目的背道而馳。所以對于變動較大部分可進行手工測試,等到趨于穩定之后再轉化成自動化測試;②項目周期長。項目本身就需要大量時間完成,或者是一個長期迭代的項目,因此有充足的時間來完善自動化測試框架;③自動化測試腳本可重用。即開發出來的自動化測試腳本可在本項目中重用,或者在其他項目中使用,從而提高自動化測試腳本的利用率,達到一舉多得的效果[13]。
自動化工具是為了支持各種測試活動而開發的軟件,也稱為測試管理工具。針對不同的測試需求,如功能測試、性能測試、安全測試、Web 服務測試、數據庫測試、可用性測試等有不同的工具。市面上可用的自動化工具可分為開源工具和付費工具。一旦手動測試用例被自動化,即可通過使用自動化工具執行腳本節省手動執行測試用例所花費的精力[14]。表1 是一些幫助測試腳本設計和執行的自動化工具。

Table 1 Comparison of automated test tools表1 自動化測試工具比較
根據目前市場上每個項目預算分配的現狀和趨勢,購買或更新許可工具的成本非常高,可能超過分配的預算。因此,使用商業自動化工具的另一種解決方案是從商業工具改編或遷移到開源工具。在上面提到的自動化工具中,像Selenium 這樣的開源工具是非常有效的,與獲得許可的自動化工具相比,其具有許多優勢并支持多種功能。
目前,Web 自動化測試工具種類繁多、五花八門。因此,選擇標準應該從以下幾方面來考慮:①發展趨勢要穩定上升;②需要有一個活躍的社區能夠進行討論;③需要是開源軟件;④支持主流的編程語言(Java、Python);⑤能支持主流瀏覽器(谷歌、IE、火狐等)。
綜合以上幾方面考慮,本文采用的技術架構為Python+Selenium。
Selenium 里包含許多工具,有Selenium IDE、Selenium Grid、Selenium RC(Selenium 1.0)和Selenium webdriver(Selenium 2.0)[15]。Selenium 能模擬用戶操作直接在瀏覽器上運行,主要功能包括:①可在不同瀏覽器上測試與瀏覽器的兼容性;②測試系統功能[16]。
Selenium IDE 是一個瀏覽器插件,用于構建測試腳本,支持Chrome 和Firefox 瀏覽器。其還可用于記錄、編輯和調試Selenium 測試用例,記錄所有由最終用戶執行的操作,并生成測試腳本,同時實現回放。
Selenium Grid 是一種測試輔助工具,可以通過在多臺計算機上進行分布式擴容,并通過一個中心點管理多個環境,從而輕松地組合多種瀏覽器與多種OS運行測試。
在很長一段時間內,Selenium remote control(RC)是Selenium 的核心部分,由于其使用了Selenium core,也即Java script 函數,運行起來比Selenium webdriver 慢很多。在執行測試腳本前,驅動與server 通信,將命令傳遞給server,并且其不支持Ajax 程序。為避免Selenium RC 的限制,人們融合Selenium 和webdriver,并提出Selenium webdriver[17]。
Selenium webdriver也被稱為Selenium2.0,Selenium webdriver 是直接驅動瀏覽器的,因此運行起來比Selenium RC 快很多。Selenium webdriver 具有以下優點:①改善了當前Web 應用程序的測試問題,支持多種瀏覽器;②支持Ajax 應用;③支持多種語言編寫測試腳本,如Java、C#、Ruby、Perl、Python 等[18];④支持在多平臺上運行,如Windows、Linux 和Mac 等,便于測試人員進行Web 應用程序跨平臺、跨瀏覽器的兼容性測試;⑤可使用Selenium Grid 進行分布式測試;⑥使用Selenium IDE 可進行錄制、回放和腳本生成。
Selenium WebDriver 與瀏覽器的通信流程如下:①對于每一條Selenium 腳本,創建一個http 請求,并發送給瀏覽器的驅動;②瀏覽器驅動中包含一個HTTP Server 用來接收這些http 請求;③HTTP Server 接收到請求后,根據請求具體操控對應的瀏覽器;④瀏覽器執行具體的測試步驟;⑤瀏覽器將步驟執行結果返回給HTTP Server;⑥HTTP Server 又將結果返回給Selenium 的腳本,如果是錯誤的http代碼,則會在控制臺看到對應的報錯信息[19]。具體通信流程如圖1所示。

Fig.1 Communication flow圖1 通信流程
基于對Web 項目實際需求功能的分析,對本文提出框架所支持的測試類型進行分析,如圖2所示。

Fig.2 Test types圖2 測試類型
(1)功能自動化測試。Web 的功能測試屬于黑盒測試,不關注內部具體實現邏輯,模擬手動操作對相關功能進行測試。主要關注是否能打開網頁鏈接,網頁顯示內容是否正確,元素的定位、識別、點擊、滑動、輸入文本等功能是否能實現,驗證碼是否識別正確,頁面上自動彈出的提示框是否正確處理[20]。
(2)兼容性測試。Web 項目要想被廣泛應用,兼容性至關重要。需要在不同的瀏覽器、操作系統上能夠被正常使用,因此要在一些主流的操作系統如Windows、MacOS、Linux 以及主流的瀏覽器如Chrome、IE、Firefox 上進行兼容性測試。
(3)性能測試。系統響應時間、并發用戶數、資源利用率等是測試的關鍵,該框架將從這幾個方面對Web 應用進行測試。
(4)分布式測試。分布式測試是指在版本迭代的回歸測試和兼容性測試時,在多臺機器、多個版本的操作系統和瀏覽器上并行執行測試,從而縮短測試時間、提高測試效率。
本文所設計的框架主要包含以下幾個功能:編寫測試腳本、執行測試腳本、生成測試報告、定位分析測試結果。
(1)編寫測試腳本。測試腳本是測試框架中最重要的部分,因為產品在不停迭代,測試用例也會不停地修改,所以腳本編寫要考慮到后期維護成本。考慮到這點,編寫測試腳本功能將分為4層,如圖3所示。
配置層用來存放config 配置文件和數據文件;數據庫層對系統數據庫進行管理;API 層采用PageObject 設計模式,將頁面元素定位方式、操作方法與測試腳本分離;測試用例層通過調用配置層和API 層封裝的方法完成測試用例的編寫。
(2)執行測試腳本。主要分為并發執行與集成自動化測試兩部分,如圖4所示。

Fig.3 Writing test script圖3 編寫測試腳本

Fig.4 Executing the test script圖4 執行測試腳本
測試用例多線程的并發執行能夠提高自動化測試框架的執行效率。采用Jenkins 持續集成工具,通過自動化部署可以完成持續集成[21]、自動構建并執行測試腳本等諸多重復工作,從而減少資源的消耗。
(3)生成測試報告。測試執行完畢之后將自動生成測試報告,并將測試報告以郵件形式自動發送給相關人員,可以是測試人員也可以是與項目相關的其他人員。
(4)定位與分析測試結果。主要通過log 和失敗的截圖進行定位與分析,log 中記錄自動化測試用例的名稱、操作步驟與執行失敗的原因。當發現自動化測試用例執行失敗時能自動進行截圖,并將截圖保存在指定位置。
(1)性能需求分析。利用Selenium Grid 測試輔助工具在多臺計算機上進行分布式測試,并通過一個中心點管理多個環境,從而對多種瀏覽器與多種OS 組合進行并行運行測試。用多線程或多進程降低自動化測試的總耗時,但容易造成內存溢出,所以執行完一個.py 文件,必須執行driver.close(),關閉瀏覽器后可釋放內存。執行測試用例時間不能太長,否則就失去了自動化的意義,一般來說100條測試用例的運行時間需要控制在2h以內。
(2)易用性需求分析。測試人員不需要對編程語言非常熟練或對測試框架的內部邏輯非常熟悉,只需搭建簡單的測試環境,輸入簡單的命令,即能進行自動化測試,生成測試報告,并將報告以郵件形式自動發送給相關人員。
(3)可維護性需求分析。軟件開發是一個迭代的過程,功能會不斷的增加和完善,所以測試用例會不斷增加,測試腳本也會隨之不斷修改和完善。因此,要求腳本能不斷作出調整,以便框架能長期使用。
(4)穩定性需求分析。框架不是只執行一次,可能每天都要執行,也可能每隔一段時間就要執行。為了保證框架的長期使用,框架要有較強的健壯性和穩定性。當輸入測試數據時會改變測試環境,而這種改變可能會影響后續測試用例的執行,所以為了保證后續測試順利執行,框架還要支持測試場景的恢復。
(5)可靠性需求分析。最基本的要求是要保證測試結果真實、可靠。測試數據也從一定程度上保證了測試的質量和完善性,所以測試數據不要隨意更改,如要進行增刪改操作,需要記錄在操作日志中。
本文基于Selenium、Jenkins、Pytest 設計的自動化測試框架總體結構如圖5 所示。將編寫、維護好的工程代碼提交到Jenkins 平臺集成,也可以從Jenkins 獲取工程代碼,或者部署到各個機器上并行執行自動化測試。執行完畢后將自動生成測試報告,并用郵件發送給相關人員。

Fig.5 Overall structure of automation test framework圖5 自動化測試框架總體結構
自動化測試框架詳細結構如圖6所示。
(1)Testcases 包用來存儲各個模塊的測試用例腳本,其包含Web 應用程序的常見功能,如登錄、注冊、關鍵詞輸入、按鈕點擊、復選框選擇等。定位頁面元素一般通過其id、xpath、link text 或css locators 來定位,即使元素名稱改變也不需要修改測試腳本,從而簡化了維護和修改測試用例的工作。每個.py 文件的命名方式都是有意義的命名,如登錄模塊是login.py,使測試人員在維護或搭建環境時,能快速定位到自己所需的腳本。

Fig.6 Detailed structure of automation test framework圖6 自動化測試框架詳細結構
(2)Lib 包中存放一些需要用到的第三方庫,如識別驗證碼的第三方庫ShowapiRequest。
(3)Screenshots 目錄用來存儲測試過程中的所有截圖,主要是失敗用例截圖和需要識別的截圖。通過失敗用例截圖,測試人員可非常容易地抓取到錯誤發生時的程序狀態,有助于開發人員分析issue。將日期和時間設為截圖的名字,并將圖片文件存儲在指定目錄下。
(4)Util 包用來實現工具類,比如獲取圖片驗證碼和生成隨機字符串。獲取圖片驗證碼的思路是先用截屏的方法browser.save_screenshot 截下整張圖并保存到screenshots目錄下,再用摳圖的方法im.crop 摳下驗證碼并保存。用第三方庫ShowapiRequest 識別保存下來的驗證碼,最后返回一個識別后的驗證碼。輸入用戶名時即可用隨機字符串類隨機生成,否則可能會與后臺數據庫的用戶名重復。
(5)Data 目錄存儲測試數據。在Web 應用程序中,終端用戶通常需要輸入一些信息,比如登錄系統通常需要輸入用戶名和密碼來登錄,像此類輸入會存儲在data 中。測試人員可以從data 中獲取輸入內容,而不需要在應用程序中輸入相同信息。測試人員可以在該目錄下存儲Web 應用程序所需的輸入值。
(6)Log 目錄存儲Log 日志,特別是失敗用例的Log 至關重要,里面會記錄issue 的關鍵時間點和信息,便于開發人員進行分析。
(7)Reports 目錄存儲測試報告,測試完畢后自動生成測試報告。Selenium 沒有生成報告的內置功能[22],所以本文設計的框架采用allure 插件生成測試報告,最后將報告用郵件發送給相關人員。
(8)Config 目錄存儲配置文件,主要是一些環境的配置,如測試機器IP 地址、操作系統與瀏覽器相關信息、測試次數等。
使用了該自動化測試框架之后,測試效率有了很大改善,測試人員可完成比傳統方法多兩倍的工作量,從而減少了測試的人力資源。有時測試用例失敗是由于Selenium webdriver 同步性的問題,而不是由于應用程序本身的缺陷。該框架減少了因同步性問題導致失敗的概率,增加了通過的概率。綜上所述,所提出的框架比改進前的自動化測試框架準確性更高。
執行5 次具有250 條測試用例的測試集,得到了如表2所示的結果。穩定執行率是指通過的用例數和產品功能導致失敗的用例數總和與總執行用例數的比值。因為產品功能導致失敗的用例,失敗原因并非框架本身的因素,所以將產品功能導致失敗的用例作為穩定的用例計算。

Table 2 Situation of test cases execution表2 測試用例執行情況
將5 次結果進行匯總得到表3。穩定執行率表明框架穩定執行的測試用例比例,并且給出的結果與手動測試用例給出的結果一樣準確。有時應用程序工作正常,但是測試用例失敗是因為同步性的問題。新提出的框架使測試用例同步正確,所以失敗率比改進前的自動化測試框架有所降低。改進前的框架是指腳本無法復用的、無法部署多臺機器進行并行測試的、沒有驗證碼識別等特殊處理的框架,所以導致維護費用高、執行時間過長、失敗率高。

Table 3 Comparative results of the proposed framework and old framework表3 新提出框架與改進前框架的對比結果
下面對本文所提出的自動化測試框架進行評估。作為一個新的自動化測試框架,需要多種類型、多方面的評估,特別是可重用性、可擴展性、兼容性和全面性等方面的性能。評估得到的實驗對比結果如表4所示。

Table 4 Experimental comparison results表4 實驗對比結果
本文提出基于Selenium 的新的自動化測試框架來測試Web 應用程序,該框架可減少編寫測試用例所需時間,并提高測試用例通過率,為測試人員提供了一個方便配置不同瀏覽器進行Web 應用測試的工具,減少了測試人員工作量。通過使用該框架,可生成定制化的測試報告,也可利用失敗測試用例的截圖分析失敗原因,測試人員可在data 目錄中維護所有數據。該框架能很好地適用于動態變化的應用程序,自動化測試的腳本也易于理解,因此使用該自動化框架可幫助團隊更高效地測試Web 程序。但由于時間限制,本框架關于驗證碼的識別還不夠完善,對于簡單的驗證碼可以使用pytest中的pytesseract 模塊和PIL模塊進行識別,而對于復雜的驗證碼,則需要使用第三方的API。希望在后期的研究中,可實現不再依賴第三方庫也能識別復雜的驗證碼。