幾個月前,筆者寫了一篇題為《自動化單元測試》的文章,內容涉及開發人員如何為業務邏輯編寫單元測試和驗證Javascript語法。在建立一個企業應用程式的時候必需瞭解這些概念:在更新要推送到產品之前必須捕獲錯誤,或可能帶來的災難性後果。
在那篇文章沒有涉及的一個領域就是“UI測試(也稱為整合測試,Integration Testing)”的觀念。閱讀了許多關於那篇文章的評論和聽到社群反饋後,我決定發表一篇在ExtJS應用程式中新增UI測試和討論企業應用程式測試策略的文章。
UI 測試:概述
正如前文提到的,UI測試與單元測試的不是同一樣東西,這個兩個概念經常造成困惑。
UI測試要做的是從主觀上驗證螢幕上的元素行為(包括外觀)是否如預期的那樣,這包括靜態(平面渲染)和動態(使用者操作給予的行為)兩個方面。單元測試則是針對小塊程式碼並客觀驗證應用邏輯。
它們主要的不同點就在於測試性質的主觀性和客觀性上。
這觀念進一步來說,就是可以把UI測試劃分為兩個組成部分:QA測試和元件測試。
- QA測試模擬的是在使用者使用應用程式時,現實世界與應用程式的互動。
-
元件測試就是將應用程式劃分成不同的塊(可重用)來驗證他們的顯示和行為。
在本文,將看到這兩種型別的UI測試。
使用UI測試的常見問題
選擇正確的工具
測試應用程式的外觀和複雜的互動是一項艱鉅的任務,因而,許多Web開發人員抵制(通常是放棄)通過UI測試來充分解決QA問題也就毫不奇怪了。
其
實,開發人員需要解決的最大障礙是為這個工作選擇最好的工具。一些工具依賴於Xpath或CSS選擇器來瀏覽應用程式,另外,還需要複雜的伺服器配置來實
現自動化測試。歸根結底,選擇富有彈性的工具非常重要,QA測試會因業務需求改變或應用程式修改而頻繁重寫,因而,測試易於建立和維護相當重要。
實,開發人員需要解決的最大障礙是為這個工作選擇最好的工具。一些工具依賴於Xpath或CSS選擇器來瀏覽應用程式,另外,還需要複雜的伺服器配置來實
現自動化測試。歸根結底,選擇富有彈性的工具非常重要,QA測試會因業務需求改變或應用程式修改而頻繁重寫,因而,測試易於建立和維護相當重要。
以筆者的經驗來說,有三種工具適合編寫Sencha應用程式的QA測試:
- Selenium
- CasperJS(需要執行在PhantomJS平臺)
-
Siesta
這些工具每一個都有突出的優點和缺點,不過,筆者個人覺得Siesta更易於配置,而且它的API可以無縫的與Sencha框架一起工作。
免責宣告:其他UI測試工具,我不主張去使用他們,我也不主張Siesta就一定是目前最“好的”工具。我只是根據我自己的經驗提供意見。
模擬資料
使用UI測試的另一個重要(經常被忽視)的問題是,測試往往不是針對線上API編寫的。不管什麼原因,API本身就不可靠:伺服器當機、網路出現延遲以及發生例外錯誤等等。
UI測試的目的是驗證顯示和行為,而不是存在於任何給定時間的特定資料。如果可能,UI測試應該模擬API資料,但這不是一個易於解決的問題。一些實現使用的是Ajax請求的靜態資料,而另一些則需要重定向網路呼叫來模擬API。
不單是Javascript模擬庫存在難以控制的問題,不過我不打算在本文深入探討這個問題。我只是想讓大家對該問題提供認識,因為它是常常會讓人感到沮喪。在示例應用程式中,使用了Sinon.js作為API呼叫的存根。
說了這麼多,可能會讓你會覺得應該使用線上API,不過,我通常只建議在驗證釋出版本的時候才使用線上的API。
示例應用程式
在示例Ext JS應用程式,可以在ui-tests資料夾找到使用Siesta編寫的QA測試(/app/)和元件測試(/ux/)。
QA測試
在/app/資料夾下,可以在瀏覽器中開啟index.html檔案來檢視QA測試的Siesta介面。在這裡的目標是執行實際的應用程式並測試使用者所期望的現實世界的互動。儘管示例應用程式是比較簡單的示例,但兩個QA測試還是演示了測試應用程式全部行為的不同方式。
第
一個測試,名為“Testtabs for data in
grids”(/app/tests/01_tabs.js),只是簡單的載入應用程式並檢查是否能確保所請求的檢視的顯示是正確。雖然這個特殊示例還比
較原始,但在應用程式基於使用者角色、喜好或其它一些邏輯動態建立它的介面時,測試結果可能會非常有用。
一個測試,名為“Testtabs for data in
grids”(/app/tests/01_tabs.js),只是簡單的載入應用程式並檢查是否能確保所請求的檢視的顯示是正確。雖然這個特殊示例還比
較原始,但在應用程式基於使用者角色、喜好或其它一些邏輯動態建立它的介面時,測試結果可能會非常有用。
第二個測試,名為“Testdouble-click functionality”(/app/test/02_RsvpWindow.js),會重新載入整個應用程式。這一次,要模擬的是Grid和標籤的互動以確保所需行為按預期執行。
必
須注意的是,這裡使用了Sinon.js檔案作為Store的JsonP請求的存根。這樣做就無須假定線上API能訪問並能正常工作,就可測試到應用程式
的功能。有許多方法可以做到這一點,在這裡選擇了重寫Ext.data.JsonP.request()的行為來自動返回模擬資料(請看/ui-
tests/app/api_stub.js)。
元件測試
在/ux/資料夾下,可以在瀏覽器開啟index.html檔案來檢視元件測試的Siesta介面。與QA測試不同,這裡的目標是分離各個元件並測試他們的行為。通過測試大型應用程式以外的元件,就可隔離已知錯誤,並保證未來的相容性。
示
例應用程式(/apuxp/tests/01_RsvpWindow.js)的唯一測試是檢查RsvpWindow檢視的顯示和行為。預設情況下,檢視
(擴充套件自Window類)將以300×300的尺寸、帶標題作為模態視窗彈出。使用Siesta,將建立一個獨立的檢視例項並驗證這些預設配置屬性。
- var defaultWin = Ext.create(`ChicagoMeetup.view.RsvpWindow`, {
- //default configs
- });
- t.is(defaultWin.modal, true, `RsvpWindow should be modal.`);
- t.is(defaultWin.title, `RSVPs for the selected Meetup`, `RsvpWindow should have a title of “RSVPs for the selected Meetup”.`);
- t.is(defaultWin.getHeight(), 300, `RsvpWindow should be 300px tall.`);
- t.is(defaultWin.getWidth(), 300, `RsvpWindow should be 300px wide.`);
- t.is(defaultWin.getLayout().type, `fit`, `RsvpWindow should have “fit” layout.`);
這非常有用,也是一個好注意,可以為了可重用性確保RsvpWindow能被自定義。在Siesta測試,還可建立另一個RsvpWindow例項,不過,這次將重寫預設值以確保初始化過程成功。
- var customWin = Ext.create(`ChicagoMeetup.view.RsvpWindow`, {
- modal : false,
- title : `Foobar Window`,
- height : 400,
- width : 200,
- layout : `card`
- });
- t.is(customWin.modal, false, `RsvpWindow should be modal.`);
- t.is(customWin.title, `Foobar Window`, `RsvpWindow should have a title of “Foobar Window”.`);
- t.is(customWin.getHeight(), 400, `RsvpWindow should be 300px tall.`);
- t.is(customWin.getWidth(), 200, `RsvpWindow should be 300px wide.`);
- t.is(customWin.getLayout().type, `card`, `RsvpWindow should have “card” layout.`);
使用Siesta強大的測試API,可以模擬元件的各種互動方式(click、drag等等)。雖然RsvpWindow元件還不足以令人興奮,但可以想象一下那些自定義的UX類的可能性。
結論
建立一個Web櫻花程式的單元測試可能是一個艱鉅的任務,但當做得爭取時,努力的回報是無價的。最後,筆者想重申以下這些要點:
- 單元測試和UI測試並不同。兩者對保持穩定程式碼都很有價值,不過他們是用來解決不同問題的。
- 注意語法。僅僅因為程式碼可以在一個瀏覽器中執行正確並不意味著它可以在每一個瀏覽器都能正確執行。
- 測試自定義元件。框架如預期那樣正常執行了,不過,不要以為UX就寫對了。
- 不要瞄準100%的程式碼覆蓋率。可能會有測試整個應用程式的想法,但要考慮維護一個複雜的測試套件的成本。
這系列關於單元測試的文章是基於筆者個人經驗來協助解決Sencha的使用者解決常見問題的。在網路研討會會學到更多。筆者會主持1月31日的Mats Bryntse來給開發人員介紹切合實際的測試Ext JS和Touch應用程式的方法。註冊地址在這裡。另外,還邀請你來分享自己的想法和經驗,希望大家可以互相幫助,使Web應用程式測試更易於實現目標。
作者:Arthur Kay
Arthur Kay has been working with the
Web since the late 1990s, when GeoCities and scrolling marquees were
all the rage. Since those early days, Arthur graduated from Loyola
University Chicago (where he studied Music and Computer Science) and has
worked in a variety of professional roles throughout the Internet
industry. Arthur currently lives in the Chicago suburbs and works as a
Solutions Engineer for Sencha, Inc.
Arthur Kay has been working with the
Web since the late 1990s, when GeoCities and scrolling marquees were
all the rage. Since those early days, Arthur graduated from Loyola
University Chicago (where he studied Music and Computer Science) and has
worked in a variety of professional roles throughout the Internet
industry. Arthur currently lives in the Chicago suburbs and works as a
Solutions Engineer for Sencha, Inc.