生活中有這麼一種現象:如果你關注某些東西,它就會經常出現在你眼前,例如一個不出名的歌手的名字,一種動物的卡通形象,某個非常專業的術語,等等等等。這種現象也叫做“孕婦效應”。還有類似的一種效應叫做“視網膜效應”,它講的是:你有什麼東西或者特質你就特别容易在别處發現你有的這類東西和特質。幹了多年測試的我就會經常發現日常使用的系統中有很多的bug,而我老婆就發現不了。今天要說的事兒是“重制難以重制的bug”,這件事兒在本周共遇見了4次:第一次是微網誌上有一篇《程式員,你調試過的最難的?Bug?是?》(後面會附上);第二次是一個同僚跟我抱怨,好幾個bug難以重制特心煩,并問我怎麼處理比較好;第三次是本周上線的産品出現了一個當時難以重制的bug,我們對它做了初步的分析;第四次是翻看史亮寫的書《軟體測試實戰》,偶爾翻了翻,竟然看到一小節在寫“處理難以處理的缺陷”。這時候,腦子裡很多東西彙集到了一起,我想還是記錄一下吧。下面是正文:
也許測試人員(尤其是對新手來說)在工作過程中最不願遇到的一件事情就是:在測試過程中發現了一個問題,覺得是bug,再試的時候又正常了。碰到這樣的事情,職業素養和測試人員長期養成的死磕的習性會讓她們覺得不能放過這個bug,但是重制這樣的bug有時候需要花費大量的時間,有的時候還有一些盲目性(因為黑盒測試的緣故,很多内部狀态是不可見的,是以無法擷取有效的資訊來做跟蹤),效率較為低下。在實際工作中,時間和進度擺在那裡,在經曆了多次痛苦的失敗嘗試之後,測試人員的處理方法一般會有如下幾種:1.向開發人員尋求幫助來重制bug;2.當做一個issue報給開發人員。可是這樣的做法存在如下問題:
1.開發人員責任心不夠強,不願意花太多精力去求證這件事情,常見的回複就是:在我這兒沒事兒啊,我也重制不了,bug關了吧。結果随後在生産系統上,bug又開始sui随機出現了。
2.就跟測試人員不擅長編碼和調試一樣,開發人員并不擅長找出bug。經過一番嘗試以後,他們也找不出什麼問題來,常見的回複同第一條是一樣的。bug上線後又出現的宿命也是一樣的。
這時候,真正的問題來了:如何捕捉難以重制的bug?這件事兒對于測試人員來說就這麼難麼?
答案并不那麼樂觀,重制“難以”重制的bug本來就是一件“難以”完成的事情。但“難以”并不是不可能,通過一系列的測試、分析方法,我們是能夠抽絲剝繭把絕大部分隐藏的很深的bug揪出來的,當然有的時候你要考慮投入産出比,但投入産出比不是本篇要考慮的,本篇隻講一些我積累的經驗。
為什麼不能重制bug?
最大的原因就是:測試人員對被測物的了解還不夠深入。
我曾經做過一段很長時間的收集和統計,那些被稱作過“難以重制”的bug最後都可以分為如下幾類:
1.環境的變更造成了bug難以重制。這裡的環境包括了:基礎軟硬體環境(作業系統、網絡、存儲、中間件、容器等等),被測物自身發生了某些變更。環境的變更一般是由于多人共用環境造成的,也有少量情況下是系統内部或者時間觸發的變更(這類bug非常難重制)。
2.沒有找到真正引發bug的操作。這些操作往往是一些不怎麼顯而易見的操作,測試人員在不經意間完成,而又忽略了這一操作,以緻難于重制bug。
3.沒有找到真正會引發bug的操作序列。很多bug的重制需要滿足多個條件。在滿足多個條件的狀态下,你做了對應的操作,bug才會被觸發。
4.bug必須使用特殊的資料才會出現,測試人員沒有意識到她使用的資料的特殊性。一種比較難搞的情況是:同一組輸入,在不同情況下(不是不同的業務情況)輸入會被轉化成不同的資料。我曾經見到過這麼個例子,程式員用系統目前時間作為随機數的種子來生成id,但是id設定的比較短,一個存儲的操作使用這個id,在一些情況下,發生了沖突,當時做功能測試這種小機率事件耗費了測試人員大量時間也沒有穩定重制,還是在性能測試的階段測試了出來。
5.測試人員由于錯誤操作,出現了誤報(這很常見)。比如,記得自己執行了step3,其實沒有,或者沒有正确執行step卻覺得正确執行了。
怎樣對付這樣的bug呢?
我喜歡James Bach 說的那句話:測試就像CSI。CSI是Criminal Scene Investigation 的縮寫,也是我非常喜歡的美國系列劇。
從我來看CSI的精髓在于:仔細觀察,詳細記錄,科學分析,嚴密推理,有序求證,大膽假設,持續不懈,團隊協作和一點兒運氣。找bug其實和CSI探員做犯罪現場調查沒什麼太大差別。得知道,你工作的重要性一點兒不亞于CSI探員。
仔細觀察:第一件事情就是要觀察,觀察你所做的一切操作和一切相關的系統回報。在一開始,觀察的重要性要遠遠大于思考,通過觀察你獲得蛛絲馬迹,這些蛛絲馬迹是你進行思考和假設的關鍵輸入。例如,我在一次測試的過程中,發現做某種操作的時候會相當慢,極少數情況下還報錯過一兩次,當詢問了開發人員後得知這個操作的背景實作步驟是:先檢視資料是否在緩存中,如果不在,則從遠端伺服器請求資料。我抓住少數情況下會報錯的這一現象,仔細觀察它的出錯資訊後猜測報錯并不是因為網絡連接配接不穩定引起的,而是由于遠端服務接口實作有問題引起的,後來重新設計了測試用例,果然找到了問題所在。如果不仔細觀察出錯資訊,就會聽信開發人員認為這是網絡不穩定引發的正常issue而錯過這個bug。
詳細記錄:詳細記錄你的操作步驟及傳回結果非常有助于回朔問題,也有助于後續分析。準備一個word文檔,和截圖工具有時候非常必要。另外,在觀察的時候,你不僅要注意被測物的最終傳回,還需要觀察過程中的一些中間狀态,往往這些中間狀态提供的資訊才是解開問題的關鍵。這些中間狀态一般會被記錄在log檔案中,是以知道你的被測物是如何記log的,log被記錄在哪裡非常重要。log給了你另外一個看系統的角度。log是有級别的,如果級别可以動态調整,在找比較難找的bug時,可以将log記錄的級别調至最低(DEBUG級)讓它們記錄更多内容。利用系統的錯誤轉儲檔案(比如linux的core dump檔案,windows下也有相應的記錄轉儲檔案的方式)分析也是個不錯的辦法(需要較高技術能力),但一般建議測試人員把這些轉儲檔案交給更專業的開發人員來分析。在我短暫的C++開發歲月中,有使用過GDB閱讀轉儲檔案的經曆,那絕對不是愉快的回憶。你瞧,測試人員的主要工作是找出可重制的bug,并不是定位它們,不是麼?
除了log,如果能有監控資訊,也要檢視他們。比如系統提供的監控平台,監控日志;應用自己的監控平台、監控日志(如果有的話);采用一些外部技術手段截取一些中間狀态資訊,如使用sniffer抓取通訊包,使用Fiddler截獲HTTP封包内容;給運作程式插樁來檢視記憶體,堆棧,線程,函數被調用情況等情況,如Jprofile,gpertool等等。
科學分析:對于黑盒測試人員來說,科學分析意味着你需要有一定的分析政策。我們需要采取一些形式化的方法來完成我們的分析。基于我的統計,缺陷難以重制有很大一部分原因是因為“沒有找到真正引發bug的操作序列“。測試人員不可能像開發人員那樣去跟入到代碼内部,設定斷點調試程式,他們主要的測試方式是直接來操縱被測物,并從外部觀察被測物狀态的改變。顯而易見,“狀态轉換圖分析法”是測試人員對付“難以重制bug”的最強有力武器之一。狀态轉化圖能夠幫助測試人員很好的選擇操作路徑,并且知道這麼做有什麼意義。“狀态圖轉化法”絕對是測試人員值得花時間學習和研究的一種方法,你可以走的很深,也可以研究得很遠(可以從MBT的方向進行拓展),限于篇幅,這裡就不展開了。在這裡推薦《探索吧!深入了解探索式軟體測試》這本書,它的第八章對“狀态轉換”做了非常實用的描述。
上文分析的讓bug難于重制的另一種原因是沒有找到“真正引發bug的特殊資料”。我的常用做法是這樣的:1.畫出系統互動圖(要真正弄清系統的邊界,這很重要),并識别出每種互動會有什麼樣的輸入、輸出資料和中間資料,識别出這些資料的規約和格式,這樣你就不會對資料有遺漏。2.考慮資料的等價類、邊界值,對這些輸入進行組合,分析資料之間是否有耦合關系,如果有耦合關系,弄明白關系是什麼,設計違背這些關系的用例,最後采用組合測試工具初步生成測試集,再人工選取最可能出問題的資料集(直覺有時候非常管用)。
嚴密推理:天馬行空對測試人員很重要,但是當你試圖重制一個bug的時候,這并不是一個非常好的方法。抓住了蛛絲馬迹,你就要推理是為什麼産生了這種蛛絲馬迹。限于工作性質,測試人員更多的會從:業務完整性、資料完整性、業務正确性、資料正确性等方面考慮問題。但是,如果測試人員對被測物的IT架構有比較深入了解的話,推理的範圍會擴大到技術實作層面,如:多線程可能引發的問題,網絡引發的問題,excepiton處理不當引發的問題,全局事務設計不當引發的問題,記憶體洩漏引發的問題,資料庫表設計不合規引發的問題等等,這些會讓你的分析推理能力如虎添翼。當然,如果限于條件,測試人員不具備這類能力,則應該在适當的時候請求開發人員協助。
有序求證:這裡隻有一點需要注意。那就是,在求證的過程中不要打散彈槍,按照你的推理一步一步的來,一個個推理的來驗證,一次隻引入一處修改。這樣才能讓你的捕蟲網編制的足夠細密。
大膽假設:有的時候,看似八竿子打不着的東西竟然存在着千絲萬縷的聯系,而你擷取資訊的過程總是一個由少及多的過程,一開始這些聯系是無法被識别出來的。通過推理,逐漸驗證,你慢慢的識别出了大部分内在聯系。但有時候這種逐漸推進的工作也會有局限性,工作如果出現了瓶頸(你試遍了你所有的假設,都沒有重制bug),這時候就需要發揮一點兒想象力了,天馬行空這時候從一定程度上又變得有用起來,當然天馬行空也不是無厘頭,還得靠我們所謂的“靈光一閃”,這号稱是潛意識在幫助你。CSI的劇情中不也總是出現這種柳暗花明的橋段麼?
堅持不懈:話不多說,有的時候你差的就是那麼一點兒點兒耐心。
團隊協作:很多情況下,重制bug不是一個人能搞定的。我們需要測試環境ready,測試資料ready,各種監控、分析工具ready,各種不同的視角開拓思路、加深對被測試物的認識。這是team work!獨行俠有時候很管用,但是終究有極限。這就是為什麼CSI是一票人在做而不是一兩個人在做。
一點兒運氣:說實在的,有的時候重制bug就是靠運氣,你不得不承認這一點。事實上很多美好的事情發生都得依靠運氣,比如中彩票。要記住的一點是,運氣是建立在你不懈努力的基礎上的。如果你一張彩票不買,你肯定什麼也中不了。但如果你堅持買上幾年,中個五塊十塊甚至二百也不是夢。
Let it go:全試過了,連運氣都沒有。你隻能放手,回到最上面我說的那兩條了:找開發來幫忙,或者給開發報issue。即使不能重制bug,也應該給開發人員提供更多資訊:如log、dump檔案、監控記錄、螢幕截圖等。做一個負責人的測試人員,把煩惱真實的留給下家,這很重要。
本文轉自 昊洋教育 51CTO部落格,原文連結:http://blog.51cto.com/zdytesting/1759134,如需轉載請自行聯系原作者