“探索性測試”在敏捷專案中的運用 | IDCF

DevOps訂閱號發表於2020-08-18


內容來源:七姑娘日記

作者:是七姑娘呀

第一次接觸“探索性測試”,是在三年前加入ThoughtWorks時的第一次QA社群活動上。同事妮子講了一個很長的PPT,細緻地將所有的探索性測試方法羅列了一遍。我只覺得有趣,卻不完全記得住。但我瞭解到探索性測試的關鍵就是,打破常規套路,先去設計一部分測試,然後去執行,再基於執行的結果發散一些新的測試思路。這不正是我平常的工作方式嗎?我為自己的“野路子”居然有如此良好的理論依據而暗自竊喜。
後來,我逐漸參與了很多敏捷專案,從簡單的單體應用到幾十個微服務互動的大型複雜系統,探索性測試的思路幫我一路升級打怪,我發現探索性測試的思路與敏捷開發“小步迭代、快速反饋”的理念不謀而合。

一、什麼是探索性測試

“探索性測試”在敏捷專案中的運用 | IDCF



“探索性測試(Exploratory Testing)”作為一個技術術語,是測試專家Cem Kaner博士於1983年提出的。有人稱其為一種“測試風格”,也有人稱之為“測試方法”,還有人將其等價於手工測試,但我更傾向於將其定義為一種“測試思路”。
它區別於某一種具體的測試技術(等價類劃分、邊界值測試、自動化測試等),強調依據當前的上下文選擇合適的測試方法,因地制宜、避免南橘北枳。它可以用來幫助測試人員分析測試場景、制定測試策略,甚至指導自動化測試。
我們對“測試”常規的理解是,知道期待結果是什麼,透過一些測試手段來驗證實際結果是否與期待一致。有點像小時候玩過的“蒙娜麗莎拼圖”:遊戲的目標很明確,你只需要設計好拼圖的步驟,再按照步驟移動,然後就能夠看到著名的蒙娜麗莎的微笑。區別是,有經驗的玩家能夠做到以最快的速度、最少的步數完成拼圖,而初級玩家則需要較多代價。
“探索性測試”在敏捷專案中的運用 | IDCF
傳統的測試方法是“先設計、再測試”。也就是說,先分析出測試點,然後針對測試點設計好測試用例,最後執行測試。這種方法在測試目標明確的情況下是可行的。然而在實際的專案中,我們面臨的測試活動要複雜的多。它更像是“打地鼠”遊戲,總體目標是將冒出頭的地鼠給打回去,但你卻不知道下一秒,它的小腦袋將從哪個洞裡探出來。
“探索性測試”在敏捷專案中的運用 | IDCF
與傳統的測試方法相比,探索性測試主張學習,強調同時展開測試設計、執行、並從結果中獲得反饋,從而持續最佳化測試。這是一種主張即興發揮、快速試驗、快速學習和動態調整的測試思維方式。
“探索性測試”在敏捷專案中的運用 | IDCF
就我看來,傳統測試與探索性測試並無好壞之分,反而相輔相成。傳統的測試方法強調有計劃地進行,而探索性測試旨在帶著使命在某個空間中漫遊,但沒有預先設定的路線,從而發現更多沒有提前預見到的問題。

二、敏捷專案中如何運用探索性測試

“探索性測試”在敏捷專案中的運用 | IDCF



這幾年我參與了多個敏捷專案,我不斷嘗試學習和運用探索性測試,也逐漸對其有了更深刻的認識。探索性測試不僅有助於我們梳理測試策略,還能在測試過程中給予指導,對自動化測試的設計也起到至關重要的作用。
2.1 運用探索性測試梳理測試策略
所謂測試策略,簡單來講,就是從“系統承載的業務”、“系統涉及的平臺”及“系統架構”三個角度出發,綜合解決“測什麼”和“怎麼測”的問題。
不同產品往往有不同的特徵,如何合理的規劃和分解被測產品,就是在解決“測什麼”的問題。
《探索性測試實踐之路》一書提到一種“漫遊地圖模型”,它將測試比擬為遊客在城市中漫遊,幫助測試人員將被測產品劃分成不同的區域,再針對各個區域的特徵,採取有針對性的測試方案。
“探索性測試”在敏捷專案中的運用 | IDCF
如上圖所示,對於遊客,旅遊攻略幫助遊客瞭解一個城市什麼地方值得去、什麼地方不值得去。那麼,對於測試人員,可以運用“漫遊地圖模型”將軟體從邏輯上進行劃分:
“探索性測試”在敏捷專案中的運用 | IDCF

  • 商業區:使用者花錢買軟體就是因為軟體的特性使得他們的業務得以完成。商業區測試型別著重於測試軟體的主要特性,因此,需要頻繁地進行迴歸測試,以持續保證這些主要特性的可用性。由於具有很高的重複性,“商業區”的測試將是自動化測試關注的重點。
  • 旅遊區:對於軟體,有些特性對新使用者更有吸引力。這一點也涉及到部分使用者許可權的測試。
  • 歷史區:軟體也一樣具有前版本的歷史遺留程式碼,這個區域的測試目的就是測試遺留程式碼和遺留缺陷。這一點在遺留系統改造專案中體現的尤為明顯。“新開發特性不影響原有特性”將成為測試重點。
  • 旅館區:當軟體“休息”時,它實際上還是非常忙碌的。旅館區模型關注的是一些輔助功能,比如軟體後臺執行等。
  • 娛樂區:對於軟體,比如一個購物網站,商業區是搜尋商品、加入購物車、生成訂單、付款等,而其娛樂區就是指漂亮美觀的UI、友好的使用者介面等。這就需要關注到使用者體驗和相容性測試。
  • 破舊區:不同於旅遊,軟體的破舊區可能存在嚴重的缺陷、安全及效能問題。這部分可能是軟體的重災區,需要關注異常測試、效能測試和安全測試。

至於“怎麼測”,每個專案實際情況都不太一樣,專案的各個階段也不盡相同。我們要依據當前的實際情況,運用測試分層理論、進行測試設計、做好工具選型。更重要的是,要根據測試執行給予的反饋及時調整策略、把控風險。
2.2 運用探索性測試指導敏捷測試過程
在敏捷開發中,我們以小步迭代的方式逐步完成產品的研發。舉個例子:我們在開發一個小型系統,該系統包含4個Feature(功能特性),每個Feature又被分解為若干個Story(使用者故事),每個Story就是系統中最小的業務單元。
“探索性測試”在敏捷專案中的運用 | IDCF

  • Feature 1:包含Story A、B、C、C、D、E、F
  • Feature 2:包含Story G、H、I、J、K
  • Feature 3:包含Story L、M、N、O、P、Q
  • Feature 4:包含Story R、S、T、U

其中,Feature 1中的Story A和B相互互動;Feature 1中的Story E與Feature 2中的Story K相互依賴;Feature 2中的Story I與Fature 3中的Story N相互關聯;Feature 3中的Story L與Fature 4中的Story R相互依賴。
假設按照產品計劃,我們即將在4個迭代中完成開發,每兩個迭代完成一次版本釋出(Release)。那麼,按照需求優先順序、需求依賴關係、團隊速率等因素,story被合理的安排到迭代1至迭代4,如下圖所示。
“探索性測試”在敏捷專案中的運用 | IDCF
那麼我們如何有效地運用探索性測試來幫助我們實施測試呢?
探索性測試中提到三種常見的測試方法:單個特性測試、互動特性測試、以及系統互動測試。運用到敏捷開發中是這樣的:

  • 首先,由於每個Story為最小業務單元,每個Story都需要在當前迭代獨立完成測試,這就是所謂的單個特性測試;
  • 其次,由於部分Story之間有依賴關係,比如迭代1中的Story A和Story B、當A和B獨立完成測試之後,我們要關注這兩個Story之間互動的測試。一個典型例子就是,A為某個頁面的UI、B為後端實現。測試Story A時,我們關心前端展示、校驗、互動等;測試Story B時,很可能A還沒有完成開發,我們需要透過API測試,人為地透過控制入參來完成後端邏輯的驗證。然而,我們如何保證前端在與後端互動時,傳遞給後端的入參是正確的呢?對於開發同學來說,“聯調”就是在解決這個問題,對於測試人員,這便是最小互動特性測試。
  • 再者,透過迭代1和迭代2,我們基本完成了Feature 1和Feature 2的所有story的開發和測試,可以完成第一次Release啦。在Release之前,我們需要完成一輪迴歸測試,測試範圍為Feature 1和Feature 2。假設Feature 1為“註冊”、Feature 2為“登入”,我們已經分別完成了註冊和登入功能的驗收,但是“新註冊的賬號是否能夠正常登入”並沒有完全得到驗證。這就是互動特性測試,旨在發現特性在各個特性在互動時的潛在缺陷。
  • 然後,在迭代3中,Story N與已經發布在生產環境的Story I發生關聯,為了更好地是適配,很有可能Story N的需要被重構。那麼我們在測試Story I時,要同同時關注與Story N的互動。
  • 最後,在迭代4以後,我們完成了全部4個Feature的開發和測試,又要進行一次上線釋出啦。同樣,在上線之前,我們又要進行一輪迴歸測試。不過這次的迴歸測試範圍不僅包括迭代3和迭代4新開發的內容,還要包含之前所有已經發布線上上的特性,也就是截至目前整個系統的測試。這就是系統互動測試,以便發現整個系統中各業務單元之間互動的潛在缺陷。

當然,這只是個比較理想的例子,在真正的敏捷開發中,我們不僅要關注功能的單點測試和迴歸測試,還要關注效能、安全、及相容性測試。但是無論哪種測試型別,測試範圍都是從“單個特性 – 互動特性 – 系統互動”逐漸演進的過程。
2.3 運用探索性測試完善自動化測試
由於敏捷開發節奏快,幾乎每個迭代、每個版本都需要完成或大或小的迴歸測試。系統演進得越來越大,迴歸測試的量也與日俱增。而在敏捷全功能團隊中,往往是四五個Dev配備一名QA,就算是千手觀音,恐怕也很難純粹靠手工完成所有的迴歸測試,那麼自動化測試就該登臺亮相了。

  • 將需求明確的、業務穩定的、需要重複迴歸測試的部分用自動化測試來實現;
  • 將需求不明確、變動頻繁的、無需重複測試的、或者需要日誌等特殊形式驗證結果的部分,配合探索性測試思路,透過手工測試來完成。

在手工測試的過程中,也可以逐漸抽取出一些新的測試點補全到自動化測試當中,這將極大地提高測試效率。
在敏捷開發中,我們運用測試金字塔的分層思想來制定自動化測試策略:
“探索性測試”在敏捷專案中的運用 | IDCF

  • 單元測試:旨在測試程式中的最小可測單元,隔離性很高、無需其他依賴、執行速度較快,因此建議在每次提交完程式碼並且透過編譯之後、部署測試環境之前完成“單元測試”。
  • API測試:主要關注在系統架構的業務邏輯層,我們透過工具或程式碼方式去呼叫特定的API,給定輸入、獲取輸出,驗證響應結果。API測試不僅要關注正常場景,更要關注異常場景。API測試執行效率比較高,可以根據專案環境穩定情況,設定每次部署環境之後啟動測試,也可以每天在固定的時間執行測試。
  • UI測試:UI測試關注使用者介面及使用者體驗。透過程式碼或工具模擬使用者透過鍵盤輸入或滑鼠操作等行為來與系統互動。由於UI測試執行效率相對較低,建議在每天環境相對穩定的時間段執行測試。
  • E2E測試:端到端測試應該覆蓋那些業務價值最高的路徑,並不關注異常場景。要做到這一點,需要在設計測試時,從終端使用者的角度來考慮,透過使用者畫像和User Journey來確定測試場景。E2E測試是迴歸測試的好幫手,可能會在版本釋出前的一段時間頻繁執行。
  • 冒煙測試:冒煙測試是一種針對軟體版本包的快速驗證策略,如果冒煙測試沒有透過,則不必進行更深入的測試。因此,我們可以從E2E測試中抽取兩到三條最核心的場景設定為冒煙測試,在每次環境部署之後啟動測試,從而快速驗證本次版本的可用性。

無論什麼樣的自動化測試,都需要設定特定的輸入,有明確的輸出。但是敏捷開發是個演進式開發的過程,一些驗收條件在這個迭代是這個樣子,在下個迭代很可能就是截然不同的了;此外,我們對系統的理解也必將經歷一個逐漸深入的過程。因此,探索性測試中的一些方法正好可以幫我們彌補這個過程。
探索性測試方法有很多,這裡對我幫助最大的是《探索式軟體測試》一書中定義的四個分類:
1)自由風格的探索性測試
自由風格的探索性測試(Freestyle Exploratory Testing)對一個應用程式以任意次序和方法進行隨機測試,不提前設定測試範圍和規則,也無需大量準備工作。
在上面我們提到,冒煙測試是從E2E測試中提取的基本場景。但是,E2E測試實際上是整個測試中最困難的,它很大程度的依賴於環境,而一個完整的環境的建立與維護可能需要花費很大的精力,特別是當有多個不同的團隊在獨立開發時。因此,當自動化冒煙測試無法進行時,我們就可以透過這種自由風格的探索性測試來指導手工冒煙測試,以快速驗證軟體包是否存在重大崩潰或嚴重缺陷。
2)基於場景的探索性測試
基於場景的探索性測試(Scenario-based exploratory testing)和傳統的測試方法有些類似,要有明確的測試的起點和終點。比如在E2E測試中,它可能基於基於user journal、使用者故事、程式的生命週期等。不同的是,它不限制路線。好比我們設定的場景是,從西安到北京,但並不限制出行方式和路線,你可以乘坐汽車、高鐵、飛機,你甚至可以繞地球一圈,只要最終能夠到達。
3)基於測試策略的探索性測試
基於策略的探索性測試(Strategy-based exploratory testing)是指將自由式探索與經驗、方法、技能和第六感結合,它屬於但不完全等同於自由式探索,它是在經驗和技能的指導下完成,比較適合有經驗的玩家。
已有的測試策略是基於測試策略的探索性測試成功的關鍵,測試人員的測試知識和經驗越豐富,測試效率就會越高、效果越好。測試新人可以從測試老手的測試路徑中學習和提取一些新的測試場景,補充到自動化測試中。
4)基於反饋的探索性測試
基於反饋的探索性測試(Feedback-based exploratory testing)是指測試人員基於“上一次”或“上一條”測試的結果來動態調整自己的測試。
舉個例子,你由於肚子疼去醫院檢查,大夫輕輕按你壓腹部某個部位,如果你沒有反應,他會試著調整部位;如果你輕微“啊”一聲,大夫便知道這個部位存在嫌疑,他很可能會再按一次,並且力道稍大一些。“啊”一聲就是你給予大夫本次測試的反饋。
再舉個例子,團建的時候,大家常常玩一個“猜數字遊戲”。法官在紙上寫下一個0-100的數字,由剩餘的人從左往右依次猜數字,猜中的人將作為“幸運兒”接受懲罰。這完全符合基於反饋的探索性測試。

  • Case 1:第一個人猜“66”,法官回答“大了”。

那麼第二個人便推測這個數字位於0-66之間。於是他調整自己的數字。

  • Case 2:第二個人猜“63”,法官回答“小了”。

那麼測試範圍就被縮小到64-66之間,很顯然,答案就在64和65當中,那麼第三位或第四位將會是那個“中獎”的人,最精彩的部分也就來了。
測試中我們也常常碰到類似的情況,一開始我們並不知道期待結果具體應該是什麼,因此無法透過自動化指令碼來完成測試。所以我們按照自己的經驗或推測先進行一組測試、再透過測試結果分析和設定下一組測試,依次迴圈直到找到最終結。等到所有的步驟和結果明確之後,就可以透過自動化指令碼去完成了。
最後,由於探索性測試只是一種思路,並不是特定的測試方法,在實際運用起來並沒有固定的套路,每個人也對它有不同的理解。但希望我們在完成測試工作的同時,能夠時不時停下來總結和思考,從而使得測試更完善、也更高效。
參考:

  • 《探索性軟體測試》James A. Whittaker
  • 《探索性測試實踐之路》史亮、高翔

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31558019/viewspace-2712457/,如需轉載,請註明出處,否則將追究法律責任。

相關文章