探索性測試總結筆記

Ant發表於2020-04-06

探索性測試

在開始實踐敏捷的時候,就一直談論著探索性測試。嘗試了許多方式,多角度覆蓋、路徑漫遊、逆向思維等等,雖然取得了一定的效果,但仍無法很自信的回答團隊做的確實是探索性測試。因為一直忙測試開發的工作,而忽略了對測試工作本身的總結和思考。所以最近特意看了一些資料和書,才把探索性測試的方法論整個整理出來。(本文許多論點取自James A. Whittaker的探索式軟體測試一書)

 

什麼是探索性測試

在測試行業非常喜歡炒作的是自動化測試,但是自動化測試有一個致命的弱點就是“預言家難題”,意思是如何才能知道被測試的軟體確實完成了它應該完成的任務,預言如何才能精準無任何差錯?機器畢竟不是人,它只能按照固定的步驟來執行計算、判斷,例如自動化執行中途出現:作業系統升級重啟、機器斷網、瀏覽器故障重啟了、頁面重新整理較慢元素在該有的時間內沒出現、HTTP丟包等等任何一些不穩定,自動化的流程就很容易崩潰並最終等待人的介入。所以過度依賴自動化是不明智的,手工測試永遠都會繼續發揮著作用。

 

如果想發現應用程式業務邏輯相關的缺陷,充分發揮主觀能動性的手工測試也是最理想的選擇。但隨著軟體測試的發展,手工測試越來越傾向於精心策劃。現代軟體專案是龐大的人員成本是有限的,如何保證在有限的時間內做最正確的事,需要手工測試在開展之前,有明確的戰略和方向,但又必須預留一定的發揮空間讓每個人的大腦可以充分運轉起來,在測試的過程中隨機應變。我們把這種測試方式稱作探索性測試:它鼓勵測試人員一邊測試、一邊計劃、他們使用在測試中收集到的資訊,影響自己進行測試的實際方式。

 

理解探索性測試有兩個前提:第一,測試之前一定會有一個全域性的方針戰略,即整體的測試計劃,它可以避免走錯大方向,該測的部分沒有覆蓋到,計劃之外的部分卻投入了大量時間。第二,測試一旦開始,沒有固定的思路,測試人員不受任何先入為主的條條框框約束,根據測試途中獲取的資訊,指導各自走不同的路徑,最終目的就是發現潛藏的缺陷。

 

探索性測試的種類

JW的書中用了一個最恰當的比如來描述探索性測試的方法論,即把測試比做一場旅程。測試的物件就是旅遊的目的地(比如說像倫敦這樣一座古老的城市),軟體的缺陷就比作是在這座城市裡所有有趣的角落。顯然,在軟體釋出週期規定的有限時間裡,你不可能把城市的每一個角落都逛遍,這樣你也就不可能發現城市裡每一個有趣吸引你的角落,你得嚴格制定你的行程和各種後備方案,但同時你也會在旅途中遇到許多突發狀況,臨時改變你的路線,就為了能走遍最好玩的地方,往往有些角落是沿途發現的沒出現在你的計劃中。這樣來比喻有計劃又鼓勵自由發揮的探索性測試,真是太貼切了!

 

為了繼續發揮這個比喻的效果,我還是引用JW書中的一些描述吧。我們在旅程開始之前,首先會做一些全域性的計劃,比如把一座城市劃分為商業區、旅遊景點、娛樂區、旅館住宿區、歷史區還有治安不太好的舊城區,這就像軟體產品裡的各個模組一樣,有主打賣點的核心功能、也有輔助功能和歷史遺留程式碼等(例如商業區就代表了真正產生經濟效益的實際業務完成區域)。當我們設計路線的時候,通常我們會拿著一份城市的地圖來做規劃,同樣的道理我們也可以拿著一份產品的說明書(F1效應)來設計探索性測試的路線。

 

這裡列舉了一些書中總結出來的探索性測試方法:

  • 指南測試法:城市的題圖通常都會標註一些熱門的旅遊景點,測試這些熱門的區域是非常重要的。不管在任何一次釋出的過程中,核心功能是肯定要覆蓋到的。指南測試要求測試人員嚴格按照使用者手冊的建議執行操作,有可能是手冊描述不到位或者核心功能並不像宣傳的那樣好。
  • 賣點測試法:此方法是鼓勵測試人員觀看銷售給客戶演示的Demo,理解銷售的角度哪些功能對客戶來說是最大的賣點,他們未必就是核心功能,但值得測試人員把它們當核心功能來對待。同時,也許刁鑽的客戶會提出各種質疑,這些質疑和稀奇古怪的問題也可以納入測試人員的設計中。
  • 地標測試法: 在旅遊的時候,如果我們設計了要到訪的地方,通常會在地圖上插上旗子,這就是地標。但是沒有人規定我們應該按照何種順序去到訪這些地標。不同的測試人員可能會選擇不同的順序,有經驗的測試人員會基於對軟體產品架構和技術層面的理解,採取一些古怪的路徑但更可能發現缺陷。
  • 極限測試法:向軟體提出難以回答的問題,比如最大可以發揮到什麼程度,承受多少使用者,承載多少資料。那個特性或功能會把軟體逼到極限運作,哪些輸入和資料會消耗軟體最多的計算能力?哪些輸入可能繞過它的錯誤檢測?
  • 快遞測試法:快遞運送的貨物,就好比軟體裡的資料,結果不同的地點轉接,拆包裝包最終到底目的地。所以快遞測試專注的是資料,跟隨它們走遍整個軟體。
  • 深夜測試法:城市燈火闌珊會在午夜過後逐漸安靜下來,商場店鋪紛紛打烊。但是軟體不應該停止工作,軟體測試人員有時應該刻意的關注在冷門時間段軟體所做的附屬工作,比如資料備份歸檔、維護監控任務的執行等等。
  • 博物館測試法:這是針對軟體的遺留程式碼,保留了些許年代的一些功能,找出它們來驗證是否有出現失效。當初開發它們的時候,甚至可能缺乏文件,但這並不意味著它們應該被忽略。
  • 深巷測試法:在每個城市,都有些地方並不吸引遊客意味著不吸引人群,但作為測試人員來說,反而是這種最不可能被用到或者最不吸引使用者的特性,容易潛藏著難以發現的Bug。
  • 通宵測試法:繁華的都市總會有通宵熱鬧的地方,比如夜總會KTV之類的,它們從不中斷。那麼應用程式是否也能堅持到最後呢?當它面臨持續不斷的呼叫、輸入、重讀重寫之類的操作,如果執行時間足夠長,就很可能會出問題,記憶體會需要回收、資料需要清空,永遠不要關閉它,保持不間斷的執行。(更多的時候會採用自動化或者機器人思想)
  • 長路徑測試法:把那個在應用程式埋藏最深的介面當做測試目標(離起始點最遠的那個介面),觀察經過的每一個介面
  • 超模測試法:針對UI的表面測試,衡量軟體的展現能力,像T型臺的超模那樣,不去關注她們幕後的辛痠痛苦勞累,跳出產品專家或測試的頭銜,以普通觀眾的角度,去關注那些能看到的介面展現,元素是否被正確繪製、是否難看、顏色風格是否一致、介面的切換變化是否表意清晰?
  • 取消測試法:此方法的思想是啟動了立即停止,特別是一些執行流程比較耗時的功能如備份還原或者搜尋,在啟動之後,立即取消。發散一點還可以變成,啟動一個耗時操作,不停止立即啟動另外一個耗時操作,以此來檢測應用程式的自我清除能力。
  • 懶漢測試法:選擇儘可能少的輸入,能不輸入儘量不輸入,能不修改儘量不修改,觀察應用程式是否能響應得出正確結果。
  • 反叛測試法:你見過去酒吧不喝酒點果汁的麼?反叛思想要求輸入最不可能的資料,或者已知的而已輸入,測試人員可以採用逆向思維、明知一些資料違反規則,卻偏偏要採用這樣的資料,或者不按照正確的順序來輸入。
  • 強迫症測試法:測試人員強迫軟體一邊又一邊接受同樣的資料,反覆執行同樣的操作,最重要的特點就是重複。此種思維方式,常常打破了開發人員設計程式碼的思路,他們預想著你會按步驟操作,卻不曾考慮過你反覆的執行第一步應該如何處理。

 

更多的討論

探索性測試蘊含著豐富的策略,將結構化思想與自由的探索方式很好的結合起來,在發現缺陷以及檢驗正確性上有顯著的效果。它能覆蓋單一場景無法覆蓋的情況,更好的模擬真實使用者的行為。那麼如何開始呢?使用者故事(User Story)會是個絕佳的起點,通常實施敏捷的團隊會要求建立使用者故事,在使用者故事中描述需求和產品的行為。測試人員可以向使用者故事衍生出的場景中注入合適的變化,通過有系統的考慮輸入選擇、資料使用和環境條件,一個場景可以衍生出多個測試用例。

 

詳細一點,給場景注入變化的手段包括:

  • 插入步驟:增加更多次的資料輸入、或增加附加的輸入、又或者訪問相關的原來不包含的頁面,前提是當附加頁面與目標頁面有共享的操作或者資料,這樣的關聯性加入才有意義。
  • 刪除步驟:逐步去掉冗餘和可選的步驟,每次只刪除一個步驟,直到獲得一個最短的測試用例
  • 替換步驟:如果某些操作可以有多種方法可以完成,就可以用替換其中的某些步驟來嘗試不同的路徑
  • 重複步驟:理解要重複的步驟和重複的順序才會使得重複的加入有意義
  • 替換資料:前提是理解應用軟體的資料來源,如果資料來源停止工作或者無法連線時軟體會變成什麼樣?
  • 替換環境:包括硬體、不同版本的瀏覽器、或者修改本地設定(禁用Cookie之類的)

無論使用何種測試技術,從剛開始就要有效的計劃和調劑測試資源,以保證團隊成功的機會。使用探索性測試也為測試人員提供了更多的機會積極參與和承擔責任,因為他們可能在途中另避蹊徑找到一些創新的思路和手段來檢測缺陷。

 

即使是探索性測試,也無法避免在測試工作中面臨的五大難題:漫無目的、重複性、暫時性、單調性、健忘性;只是探索性測試能夠基本將這些困難很好的解決。這裡其實個人感觸最深的是重複性的問題,每一次有程式碼提交也好,功能增加也好,不可避免的要做許多重複的工作,沒有任何人能自信滿滿的說,那些功能因為在上個月我們測試過了,所以這次就能夠直接忽略。

 

這裡也推薦一個經典的比喻,軟體的Bug就像是農場裡的害蟲一樣,軟體測試一遍又一遍的覆蓋檢測掃面就像農民一次次的噴灑農藥一樣,只要你的面積足夠大,總是能發現並殺死大部分的害蟲,但是也總會有一小部分的害蟲是逐漸適應了你的農藥對它免疫了的。這時候,無論你重複多少次,這些害蟲也是無法被殺死的,最終就導致了沒有任何軟體能無缺陷的釋出。其實按照農民針對害蟲農藥免疫的問題,不難想到解決的辦法就是:改變配方。當你使用探索性測試改變思路,去做下一次的迴歸測試的時候,因為你的操作順序變了,測試資料變了,那些對以往測試免疫Bug也會因為無法適應而逐漸顯露出來並被幹掉。但是注意你注入的變化帶來的配方改變,並不是武斷隨意的,而是充分基於測試人員對產品技術、功能、架構的理解,融入過往經驗真正有價值的變化。(最終這些變化都體現在了用例的設計中)

 

探索性測試也並不意味著完全的手工,因為要最大程度的發揮人的主觀能動性,就勢必要避免人的時間花在繁瑣重複的勞動中,所以適當的開發工具降低人無謂的勞動是很有必要的。同時,測試開始之後比較側重當前的狀況,精力大多被當前發生的事情所吸引,而沒有功夫去思考下一步,或者說靠腦袋來記憶一定是不可靠的,例如這個介面被測試過了多少次,被多少人測試過,每個API又被覆蓋了多少次…… 測試用例的頻繁更新並不是解決這類記憶問題的好方法,我們依然可以想辦法從工具開發的角度,幫我們記錄追蹤這類資訊。例如:一條漫遊路徑可以代表實際任何數量的測試用例,如果我們努力的把漫遊路徑對映到軟體特性和缺陷上,留下來的記錄會幫助所有測試人員瞭解內部情況,包括哪些測試方法是有效的,哪些地方是最頻繁出問題的。

 

展望未來的軟體測試應該是什麼樣子?在Google如何做測試中談到過這個話題,不過在JW的書中,又有一些新鮮的概念,比如測試百科。它強調測試是一個經驗不斷積累的過程,包括測試用例的設計、工具的使用和效能指標的參照等等,當人們把這些為了某個產品而付出研究的成果總結成更加通用的可參考或借鑑使用的一條一條經驗,就形成了測試百科。它可以避免測試人員的損失給團隊帶來的巨大影響。而且就像寫的程式程式碼能最大程度被複用一樣,軟體測試的步驟、手段、方法、策略也應該被最大程度的複用。甚至程式設計的時候,可以使用成熟的框架,為何測試就不能產生成熟的框架直接使用呢?


一些摘錄

  • 每一個好的缺陷背後,都可能藏著一個更好的缺陷,在你確實瞭解缺陷的影響程度和破壞力之前永遠不要停止探索。
  • 測試人員的績效不是通過他們找到了多少Bug來評估的,而是他們究竟提高了多少開發人員的工作效率和工作質量,從而反應在產品的質量上。
  • 自動化測試在迴歸測試盒應用程式介面測試方面最有優勢,而手工測試在驗收測試盒使用者介面測試上效果更佳。手工測試因為由人來做,可以執行非常複雜的業務邏輯,它雖然速度更慢但並不拖沓。自動化測試,擅長低階別的細節如不正確的返回值、錯誤程式碼、記憶體使用情況等,快速但阻力也巨大。
  • 測試人員當然需要讀寫程式碼,而且最好的選擇是直接從產品的錯誤處理程式碼入手,這樣能一眼發現何種輸入資料、輸入順序能把產品逼到極限。

宣告:轉載請註明原文出處。


相關文章