軟件測試修煉之道之——診斷
真正有效的缺陷修復要求思維方式既開放又有條不紊,解決方法既創新又注重全面綜合,這和軟件開發的其他很多方面是一樣的。
一種調試方法:提出一個可能提供解釋的假設,然后再構建實驗去證明你的假設,如下:
1、按照你對軟件運行情況的理解,提出一個可以導致這種運行狀況的假設
2、設計一個實驗,證明你的假設正確與否
3、如果你設計的實驗不能證明你的假設,那么重新設計一個實驗,然后再次進行實驗
4、如果實驗支持你的假設,那么繼續進行實驗,直到能證明或偽證你的假設
這種方法十分有效,但卻十分抽象,怎么才能把它轉化為實際行動呢?
不同類型的實驗:首先,你可以檢查該軟件內部狀態的某個方面(直接運行程序,利用調試器運行等),然后你可以改變軟件運行的某個方式(改變輸入參數,換一個運行環境等),看它的結果是否有所不同,最后,你可以改變軟件本身編碼的邏輯,檢查這種變化的影響。
做出什么樣的選擇要由你的假設的性質而定,而能否做出最佳的選擇取決于你的經驗和直覺,記住:你的實驗必須要有一個明確的目標。
實驗必須起到驗證的作用:如果假設始終成立,盡了最大的努力也無法推翻它,那么可以底氣十足的宣稱你的假設堅不可摧。
每次只做一個修改:多個修改會導致錯誤的結論。此規則適用于任何可能影響軟件運行的要素。
記錄你所做過的調試:定期回顧你已經嘗試過的實驗和學到的東西。
不要忽略任何的細節:凡是你不明白的都是潛在的缺陷。
相關策略
插樁:最簡單,最直接的方法,充分利用語言環境,收集和整理數據,評估任何代碼,測試相關條件。
假設你正在追蹤java代碼中數據結構方面的錯誤,并依次處理各個節點:
while(node != null) { node.process(); node = node.getNext(); } |
會得到提示:有節點被處理了多次,但我們并不知道不止一次返回的是哪些節點,此時可以使用插樁技術解決這個問題:
HashSet processed = new HashSet(); while(node != null) { if(!processed.add(node)) { System.out.printfln("The problem node is:" + node); } node.process(); node.getNext(); } |
我們可以使用插樁技術編寫出自調試軟件。
分而治之:二分法,是一種搜索策略,但是不要太依賴于這種方法,只有當你的搜索空間可以被均分成兩部分時才是最有效的。
利用原代碼控制工具:有時我們會陷入回歸狀態,即,一個缺陷本來不影響正常運行,但做了改變之后卻變成了實實在在的缺陷,此時在回歸跟蹤時有一個特別有價值的工具——源代碼控制系統。
聚焦差異:通過比對差異尋找出最有可能的問題。
奧卡姆剃刀:其他條件相同的情況下,最簡單的解釋是最好的。
調試器:在代碼運行的時候對代碼進行檢驗、設置斷點、單步調試、檢查程序運行狀態。
為什么要使用調試器?
1、在開發過程的初期,調試器是非常有幫助的,對代碼進行單步調試由助于使我們確信軟件運行的結果和我們想要的實現時一致的。
2、如果我們想讓代碼以一種特定的方式運行,就可以使用調試器來確認或反駁這個想法。
3、最后,調試器可以幫助我們探究看不懂的代碼。
然而,隨著時間的推移,會發現我們使用調試器的時間越來越少,而更多的是編寫一個測試程序,因為調試會話是短暫的,而測試是永久性的。測試不僅現在證明了代碼是工作的,而且今后仍能證明,還能被其他的團隊成員運行甚至改善。
在診斷期間有無數的方法會誤導人,因此這里我們來一起看看所謂的陷阱。
你做的修改是正確的嗎?如果你做的修改似乎沒有任何效果,那么你并沒有改到點子上,因此要在潛意識里時刻提高警惕。
驗證假設:了解你正在做什么樣的假設,對它們進行嚴格的檢驗。
多重原因:面臨多種原因的最常見信號是一種你處于模糊狀態的感覺——發生了一些似乎沒有明顯解釋的怪事情,最富有成效的解決多原因缺陷的辦法是 對問題進行隔離,并找到一個方法來重現缺陷,重現的缺陷產生的原因只依賴于多個原因中的一個,而不依賴于其他原因。另一個方法是開始先找尋同一區域內其他 較明顯的缺陷,處理這些缺陷有時可以掃清障礙,讓你理解得更透徹,使初始問題更加凸顯。
流沙:模糊感覺產生的另一個原因是一個不斷變化的基礎系統。面對一個不斷變化的基礎系統,停下手頭工作并弄清是什么在變化,為什么在變化。
調試是很艱苦的,有時簡直苦不堪言,當你看不清前進的方向的時候可以試試以下的技巧:
旁觀調試法:最有效的一個掃除障礙的策略就是向其他人求助,解釋問題會幫助你理清思路。
角色扮演:角色扮演在解釋和探討問題時十分有用,特別在涉及那些互相獨立的系統之間相互作用的問題時。
換換腦筋:讓潛意識幫助自己。
做些改變:有時候,完全陷入困境之中,做些改變是十分必要的,任何改變都可以,也許它不會告訴你任何東西,但有時它會讓你感到驚奇,讓你驚奇的事總會教給你一些東西。
福爾摩斯原則:當你排除了一切不可能后,無論剩下什么,無論它多么不可思議,也一定是真相。
堅持:雖然有時候看起來不是這樣,但實際上任何一個缺陷都是可以被診斷的。只要有足夠的時間,付出足夠的精力和決心,一定會解決的。
無論如何,當你診斷出了問題的所在,在進行修復之前,務必要驗證診斷,可以向其他人解釋你的診斷,也可以檢查源代碼的原始副本,嘗試和他人討論并假設自己是錯誤的,這樣可以讓你信任自己所做的診斷,也就可以開始著手進行修復了。
本章至此告一段落,一旦確診,接下來的我們就該聊聊修復的問題了~
相關鏈接: