我們做了大量工作,可自動化UI測試依舊實現不了

對開發者而言,測試的重要性不言而喻。在發佈新功能前,開發者需要確保已有功能有效,這就需要將每個發佈版本給到QA團隊執行人工迴歸測試。然後,測試人員或QA團隊花費數天時間執行腳本以尋找Bug。本文是Steven Lemon所在團隊遇到的手工編寫自動化UI測試的問題總結與反思,希望給廣大開發者借鑑和啓發。

爲什麼需要自動化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可能做的工作要比預期多、自動化框架的不穩定性和糟糕的錯誤信息,誰負責編寫測試用例以及誰在進展不順利時提供支持。最後,是否已經將手工編寫測試與其它商業產品和寫更多集成測試、單元測試的方式進行了比較,或者與編寫“皮下”測試進行了比較。

原文鏈接:Our team’s troubles with hand-written automated UI tests

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章