我們做了大量工作,可自動化 UI 測試依舊實現不了
發表于:2019-10-09來源:infoq作者:Steven Lemon點擊數:
標簽:
對開發者而言,測試的重要性不言而喻。在發布新功能前,開發者需要確保已有功能有效,這就需要將每個發布版本給到 QA 團隊執行人工回歸測試。然后,測試人員或 QA 團隊花費數天時
為什么需要
自動化 UI
測試?
隨著時間的推移,軟件增加的新功能會越來越多,腳本規模越來越大,執行人工測試的時間越來越長。對于人工測試的依賴開始變得棘手,因此,
開發人員開始尋找替代方案,自動化 UI 測試開始被注意,這會用自動化框架代替人工繼續運行相同的
回歸測試腳本。畢竟,人工測試的缺點已經非常明顯,比如:
人工回歸測試是一項繁瑣的工作,每個人都樂意看到替代方案;
自動化 UI 測試解放了 QA 團隊針對臨時的和探索性案例的測試時間;
人工回歸測試需要花費很長時間才能完成,很小的延遲就會讓發布面臨風險。也許需要重新測試,或者開始時間被向后推遲幾天,或者回歸環境需要同時給 2 個不同的發布版本共享;
發布節奏受到人工回歸測試的限制。兩天以上的人工回歸測試意味著最好的情況下能夠一個月發布兩次。而且,開發者需要一次性發布所有東西。要么全部發布,要么什么都發布不了,因為需要將所有東西一起測試;
自動化測試是可視化的,可以在特定設備上運行,并展示給用戶;
自動化意味著可以一邊開發一邊進行回歸測試,減少等待時間。
當然,即便人工測試有很多缺點,手工編寫自動化測試也不是唯一的解決方案,購買一款商業工具也可以創建并管理測試?;蛘?,也許框架自帶一個內置的自動化方案。那么,這篇文章不適合你?;蛘?,你可以考慮使用
Selenium 或者 Appium 之類的工具來手寫測試。但是,經過數月的嘗試,我們團隊決定放棄其他的測試方式,因為那些被證明對于我們的測試套件、架構設計和期望來說并不是一個好的選擇。在這個過程中,我們吸取了很多教訓,遇到了許多本應該提前考慮到的問題。
遇到了哪些問題?
應用程序架構
根據應用程序的組織結構以及增長趨勢,你可能會發現自動化需要花費不太合理的時間來設置。
UI 自動化是編寫測試步驟的一部分,也是設置測試基礎設施的一部分。如果遵循 Page Object Model 模式,那么你會為應用程序中的每個頁面和控件創建模型,因而測試可以找頁面或控件上的元素并與之交互,需要編寫的基礎設施代碼量取決于項目本身。你是否有一些頁面有許多不同的輸入,或者許多工作流分布在許多特定的頁面上?是否有一個可復用的控件庫,還是每個控件都隨著 UI 的變化而定制?在此之前,你開發應用程序的方式決定了需要花費多少精力來編寫測試基礎設施。反過來,這也影響了需要多長時間來編寫自動化 UI 測試。
預期效果
在開始之前,要想清楚你需要自動化測試的目的,確定好預期效果。如果是對回歸和生產中先前發現的 Bug 進行記錄,你期望用自動化 UI 測試捉到其中的多少 Bug 呢?
有許多情況,UI 測試是發現不了的,比如:
不在人工回歸腳本路徑內的問題。如果不是在測試步驟中顯式包含的 Bug,多久會被發現;
功能及其測試都不正確的時候;
邊緣情況或者不常見場景的 Bug;
在
單元測試和集成測試中能夠捕獲到的 Bug;
在應用程序中無法看到結果的任何操作。避免只是為了自動化測試而隱藏應用程序中的數據;
可視化錯誤;
性能問題;
任何太復雜和難以自動化的測試案例。
自動化測試在流程中扮演什么角色?它們是如何支持 QA 團隊和回歸流程的?也許,你的目的是解放 QA 的時間,而不是發現 Bug。你可以跳過 QA 能夠覆蓋的區域,執行更詳盡的臨時性和探索性測試。你期望自動化 UI 測試能夠發現的內容,應該告訴你選擇包含哪些部分以及計劃為多少部分編寫測試。
期望的回報
比較編寫測試的時間和可能節省的時間是比較容易的。比如自動化一個功能可能會花費 200 個小時,而這為每次發布帶來的時間節省可能是 20 分鐘。所以,在開始之前,開發人員需要想清楚期望得到的回報,以及愿意為此花費的時間。
負責編寫測試的人員
你可能會期望通過使用 Page Object Model 模式,開發者可以編寫測試基礎設施來給 QA 用來編寫測試。我們的經驗并不是這樣的,開發者需要同時編寫基礎設施和測試。
測試基礎設施可能并不能在多個
測試用例間復用。如果不復用,你會需要一邊編寫支持代碼一邊編寫測試代碼;
編寫測試可能需要對應用程序做許多更新;
自動化框架并沒有提供足夠多的信息來知道測試失敗是由于基礎設施還是測試用例;
如果 QA 團隊缺乏編碼或自動化經驗,你可能很難讓這個框架易用;
測試用例需要太多應用程序內部的知識;
測試的脆弱性導致開發人員需要不斷修復測試基礎設施;
當踐行自動化測試理念時,請讓所有有意擴展和維護測試的人參與進來。確保你正在做的事情適合他們的技術棧并且理解你的應用程序。
干凈的,用于測試的數據集
剛開始的時候,你可能使用平時開發所用的同一個
數據庫。然而,不久之后,你就會花費越來越多的時間來處理數據集。
你需要發現先決條件而不是預先設置好,或者它們應該很容易創建;
隨著更多的數據被創建,你的 UI 會發生變化。例如,額外的數據將一個元素擠出頁面,測試用例會失敗,因為它們不能與之交互;
同一個測試可能會在同一分鐘內重復運行。你需要檢查一個元素是由當前測試創建的還是由先前測試創建的;
測試用戶遇到了預料之外的狀態而導致測試用例失敗,需要人工干預或者測試用例預先篩選處于每個無效狀態的用戶;
對數據集的徹底更改會改變你一直使用的數據。例如,你可能定期清除開發數據庫或者從另一個系統導入數據來刷新;
并行的測試運行或者開發者使用同一個數據庫導致的意外交互和測試失??;
針對多個環境運行測試用例。在開發時,針對 dev 數據庫而在驗收時針對回歸環境。
每一個測試都有各種需要設置的先決條件。依賴自動化測試來安裝它們的先決條件會將每一個測試轉變成一條長動作鏈。這些額外的步驟不僅會使測試的編寫和運行速度更慢,還會使測試更加脆弱,而且使跟蹤失敗點更困難。使用干凈的數據集,可以擁有已知的測試條件和測試用戶,類似于如何在單元測試中使用母對象。
開發人員想要一個可以重置并填充固定數據的數據庫。如果還沒有這種數據庫,那么將需要大量新的基礎設施:一個新的數據、一個填充合法測試數據的工具、指向新數據庫的 API 以及用于部署這個環境的構建管道。
UI 框架和組件
每一個測試都需要考慮 UI 組件能做的所有事情,比如,不能在測試期間重置數據庫等。
我們點中某個元素,則測試通過;
后續運行向這個列表增加更多選項,將目標擠出屏幕,我們需要更新測試在點擊之前跳到這個元素;
這個列表變得如此長以至于 UI 虛擬化,目標不再存在于頁面上,不能再跳到這個元素,而是需要緩慢滾動來在列表中搜索目標;
列表中的重復顯示,需要指出哪個元素是當前測試的目標;
另一個元素變大,使整個列表處于屏幕之外。在與之交互前,需要先滾動到這個列表;
之前運行的測試由于失敗沒有完成,而留下測試實體處于隱藏整個列表的狀態。
自動化測試經常失敗
自動化測試經常失敗,而且通常,并不知道失敗的原因,因為可能的情況有很多,比如:
使用的自動化框架不能獲取屏幕上的元素;
自動化框架不能識別應用程序是否已經啟動;
測試驅動不能連接;
遇到了一個 UI 組件的邊緣情況;
一個元素被擠出屏幕,自動化框架不能與之交互;
測試在不同的屏幕尺寸和分辨率上的運行不同,因為不同的元素可能在屏幕上,也可能不在屏幕上;
每次測試運行,沒有一個干凈的、獨立的數據實例而導致前面提到的所有問題。
我們使用 Appium 和 WinAppDriver,而對于大部分失敗測試,我們得不到有用的錯誤信息,沒有日志和異常跟蹤棧,比如因為一個元素找不到而導致測試失敗,但是我們沒辦法知道是哪個元素找不到。更糟糕的是,由于失敗是斷斷續續的,而且可以是特定設備或環境,因此需要花費很長的時間來確定失敗原因。
解決測試不穩定性的一種方案是運行每個測試直到它通過。這引起了一些問題:測試周期更長;更難從測試中及時獲取反饋等。其次,這使得編寫新的測試用例更困難,而且可能要等待 10 分鐘或更久來測試單個變化。理想情況下,持續跟蹤測試用例,并將收到的模糊錯誤信息分組。當沒有可用日志時,知道測試用例什么時候開始是一個很關鍵的線索。
為了跟蹤測試的不穩定性,我們維護了一長串可能導致錯誤的因素,這包括測試套件和應用程序中所有的邊緣測試用例和 UI 交互。創建這個列表不僅花費很長時間并需要很多嘗試和錯誤,而且還增加了其它開發者共享測試套件的學習曲線。
重構困難
自動化 UI 測試很難重構。測試運行可能需要數個小時,使得很難獲取反饋并進行修正。一些測試可能嚴重依賴精心安排的時間點,一旦偏離則可能發生任何事情。
由于自動化測試對團隊來說可能比較陌生,你需要面臨由于開發者嘗試找出且爭取在測試用例中應用的最佳策略而導致的多種不同方案。擁有不同的方案使得參與項目的新人很難分辨哪個是最佳方案。每當對應用程序的 UI 做出改變時,都會產生后果。你可能發現自己需要修改大量自動化 UI 測試,每一個都需要不同的實現。
人的因素
當引入一個新工具、技術或者流程到一個團隊,需要考慮各種人的因素:
使用新工具的體驗如何?是沮喪還是緩慢?
有人愿意成為新技術的捍衛者嗎?他們離開了,誰來接管?
當工具延遲時怎么辦?當你沒有時間時,自動化測試會被放棄么?業務能容忍為了給新功能增加自動化測試的額外時間嗎?
如果這個工具在團隊中的聲譽不好怎么辦?
每一個人都認同編寫自動化測試的價值,還是認為這是在浪費時間?
正如已經總結的,關于這些測試的價值有很多潛在痛點和問題。如果沒有解決辦法,你的測試套件不可能持續很久。
注意事項
也許,創建自動化 UI 測試看起來不是一個有吸引力的選項。然而,你也不想花費很長時間來進行人工回歸測試,那么有哪些其它選項嗎?
不要嘗試自動化所有人工回歸腳本
事實上,對于自動化測試所能涵蓋的范圍,并不是原來所用的全部人工回歸套件,因為有些組件太過復雜或者太耗時間,是不值得進行自動化的,比如:
長鏈動作無法拆分。UI 測試的不可靠性使得通過一次運行完成所有測試具有挑戰性;
測試與其他的應用程序交互;
檢查 PDF 和其它生成文件的輸出;
與
Windows 系統或者
Windows 文件系統交互的測試任務;
后續運行將有不同結果的測試:測試可能會被之前運行的測試結果影響。人工回歸可能兩周發生一次,而自動化 UI 測試可能一分鐘或一小時重試同一個測試許多次,增加了沖突的機會。
如果測試運行失敗或者半途崩潰可能導致應用程序處于不一致的狀態。這時,或許需要人工進行干預來修復。
如果對應用程序某個部分中顯示的數據沒有足夠的控制,則很難設置測試的先決條件。
測試人員是否必須在應用程序中尋找匹配的數據,而不是創建數據或者直接導航到相應的場景?
注意:別太教條,沒必要強制在不適合的場景中使用 UI 自動化測試。這些測試不僅很難編寫,也很不可靠并很難維護。在你開始之前,最好認識清楚哪些部分可以自動化,任何將測試自動化的開發者都有說“不”的自由。
先補充測試金字塔的其它部分
任何單種測試不能提供百分百的覆蓋率。你想要各種級別特異性和獨立性的測試,金字塔底層的眾多特定獨立的測試。然后,越來越少的測試變得更不具體且覆蓋的應用程序更多。單元測試在底層,然后是集成測試,再然后是端對端測試。
金字塔的每一層都協調配合,擁有不同的優勢和弱勢。
如果可能,我們將在單元測試和集成測試覆蓋盡可能多的部分。這些測試易于編寫,提供更多詳細反饋,而且可以在開發期間運行。單元測試更適合覆蓋邊緣測試案例和錯誤場景。根據應用程序,自動化 UI 測試可以覆蓋 UI 邏輯,而單元測試可能不能覆蓋。自動化 UI 測試還可以保證應用程序中的多個部分如預期那樣工作。
沒有一種測試可以提供完全的測試覆蓋。如果已經有單元測試和集成測試,可能已經覆蓋了人工回歸測試腳本的步驟。編寫完全的自動化 UI 測試來覆蓋已經覆蓋的東西是價值不大的。與其用自動化 UI 測試完全取代人工回歸測試,為什么不用其他各種類型的測試的結合來取代它們呢?
其他選擇
你是編寫 UI 自動化來測試 UI,還是用來促進端對端測試?如果不需要測試 UI 層,那么“皮下”測試(subcutaneous testing,指在 UI 層之下執行的測試)可能是一個更好的選擇。這個方案允許在 UI 層之下執行端對端測試。與其點擊按鈕或者填寫文本框,開發者可以調用事件處理器并直接在視圖模型上設定公開屬性。這個方案避免了與 UI 交互和使用自動化框架的困難。這個方案的缺點是,根據應用程序使用的技術,可能沒有太多特定的指南。我們的應用程序是用 UWP 編寫的,因此不得不自己找方法在模擬 UI 的測試框架中運行。一旦開始生效,它會被證明比自動化 UI 測試更快且更易用。
結束語
UI 自動化測試的潛在優勢令人興奮:發現 Bug,解放 QA 時間,消除人工回歸測試,開發者在過程中獲取反饋。然而,與任何新技術一樣,需要一些提前調查。在開始手動編寫自動化人工回歸測試套件之前,上面已經提出了一些問題。期望發現的回歸 Bug、應用程序的架構或期望編寫和維護測試用例的人可能都不是很適合。這個過程存在一些挑戰:處理不可靠數據、UI 可能做的工作要比預期多、自動化框架的不穩定性和糟糕的錯誤信息,誰負責編寫測試用例以及誰在進展不順利時提供支持。最后,是否已經將手工編寫測試與其它商業產品和寫更多集成測試、單元測試的方式進行了比較,或者與編寫“皮下”測試進行了比較。
原文轉自:https://medium.com/@steven.lemon182/our-teams-troubles-with-hand-written-automated-ui-tests-cb189cbbff90