《軟件測試的藝術》讀書筆記(一)

這是一本於 1979 年出版的書,比大多數中國互聯網從業者的年紀還要大,但其中的觀念卻仍然適用。
軟件測試常常被計算機專業的畢業生當作自己能力不足以做開發工作的「備選」職位,似乎大家默認覺得這個崗位的要求會比程序員低。
事實也確實如此,從薪資來說,軟件測試尤其是功能測試的待遇比程序員低很多。即使是需要編程基礎的自動化測試,月薪也比同樣工作經驗的程序員低了三分之一到四分之一。但即便如此,就像大多數初級程序員普遍缺少編程系統知識一樣,軟件測試工程師們的資質也是良莠不齊。這不僅體現在基礎工作技能如文檔編寫、溝通能力上,更體現在他們本應掌握的職業經驗和思維上。或許很多人會覺得自己的測試水平不錯,日常的測試任務也能很好的完成,沒有出現重大的疏漏。然而,這樣就算優秀的軟件測試工程師了嗎?

1 測試能力的自我評估

第一章作者先出了一道測驗。

我們要求設計一組測試用例(特定的數據集合),適當地測試一個相當簡單的程序。為此要為該程序建立一組測試數據,程序須對數據進行正確處理以證明自身的成功。下面是對程序的描述:

這個程序從一個輸入對話框中讀取三個整數值。這三個整數值代表了三角形三邊的長度。程序顯示提示信息,指出該三角形究竟是不規則三角形、等腰三角形還是等邊三角形。

作為產品,我能想到的就是:

1. 提供幾組有效數據,分別符合不規則三角形、等腰三角形和等邊三角形的條件
2. 提供無效數據,例如只有 1 個或者兩個整數,提供 3 個小數。

我們再來看看參考答案:

用你的測試用例集回答下列問題,藉以對其進行評價。對每個回答「是」的答案,可以得 l 分:

1. 是否有這樣的測試用例,代表了二個有效的不規則三角形?(注意,如 1,2,3 和 2,5,10 這樣的測試用例並不能確保「是」的答案,因為具備這樣邊長的三角形不存在。)

2. 是否有這樣的測試用例,代表一個有效的等邊三角形?

3. 是否有這樣的測試用例,代表一個有效的等腰三角形?(注意如 2,2,4的測試用例無效,因為這不是一個有效的三角形。) 

4. 是否能少有三個這樣的測試用例,代表有效的等腰三角形,從而可以測試到兩等邊的所有三種可能情況?(如 3,3,4;3,4,3;4,3,3) 

5. 是否有這樣的測試用例,某邊的長度等於 0?6. 是否有這樣的測試用例,某邊的長度為負數?

7. 是否有這樣的測試用例,三個整數皆大於 0,其中兩個整數之和等於第三個?(也就是說,如果程序判斷 l,2,3 表示一個不規則二角形,它可能就包含一個缺陷。) 8. 是否至少有三個第 7 類的測試用例,列舉了一邊等於另外兩邊之和的全部可能情況(如 1,2,3;1,3,2;3,1,2)?

9. 是否有這樣的測試用例,三個整數皆大於 0,其中兩個整數之和小於第三個整數?(如 1,2,4;12,15,30)

10. 是否至少有三個第 9 類的測試用例,列舉了一邊大於另外兩邊之和的全部可能情況?(如 1,2,4;1,4,2;4,1,2)

11. 是否有這樣的測試用例,三邊長度皆為 0(0,0,0)?

12. 是否至少有一個這樣的測試用例,輸入的邊長為非整數值(如 2.5,3.5,5.5)

13. 是否至少有一個這樣的測試用例,輸入的邊長個數不對(如僅輸入了兩

個而不是三個整數)? 

14. 對於每一個測試用例,除了定義輸入值之外,是否定義了程序針對該輸入值的預期輸出值?

如果你和我一樣只得了 3~4 分,也很正常,因為據說高水平的專業程序員平均得分僅 7.8(滿分 14)。

2.1 軟件測試的心理學

很多人和我一樣,陷入了一個誤區,認為軟件測試的目的是證明軟件完美無缺,只有不存在錯誤的測試才是成功的。
而作者舉了一個例子,假如你生病了去醫院檢查身體,什麼樣的檢測結果才能稱作成功?是明明你受到病痛的折磨,花費了金錢和精力做了大量檢查,卻沒有發現任何問題,還是通過檢查確定了問題,醫生可以據此給出診療方案呢?軟件測試也是如此,我們的目的應該是儘可能的發現錯誤並修復它,以此提高軟件的穩定性和可靠性。要證明軟件的完美無缺本身就是個「不可能完成的任務」,抱着這樣的想法,軟件測試人員就會傾向於適用更不容易產生錯誤的數據進行調試,從而避免出現更多錯誤,而這背離了軟件測試的初衷。

測試是為發現錯誤而執行程序的過程」。

2.2 軟件測試的經濟學

黑盒測試:不去管程序的內部邏輯,用所有符合條件的數據輸入進行測試。但是,就拿常見的註冊功能來說。僅僅是密碼這一項,支持字母、數字和常見符號,要列出所有的可能性,光是數字和字母的排列組合就是個天文數字。就算是非測試人員也能看出來這樣的測試會花費很長時間並且沒有必要。白盒測試:在考慮程序內部邏輯結構的基礎上,將每一條語句可能存在的邏輯路徑都執行一遍。和黑盒測試一樣,即使是一個簡單的程序,邏輯路徑的分支數量也十分龐大。況且,邏輯測試也存在缺陷,無法發現設計規範問題、缺少必要路徑的問題和數據錯誤。
總之,從成本考慮,程序測試應該以數量最小的測試用例發現更多的問題,以最小的代價取得最大的成果。

2.3 軟件測試的原則

原則 1:測試用例中一個必需部分是對預期輸出或結果的定義

常見的錯誤是對輸入和輸出的定義都很模糊,例如下面這個測試用例:

 上圖中存在以下問題:

1. 剪切的組件消失應該是預期結果而不是操作步驟。

2. 顯示正確本身就是一個十分模糊的定義,應該使用更加精準的描述:其中包括組件行數、粘貼後選中狀態、參數內容等。

原則 2:程序員應當避免測試自己編寫的程序

在我還是遊戲策劃的時候,經常對程序員同事對錯誤的「視而不見」感到不可思議。
明明是只要按照正常流程使用就能立即發生的錯誤,居然到了測試階段才發現。現在想來,除了工作流程的問題(當時的團隊沒有要求程序員自己按照使用流程對程序進行驗收的步驟),更重要的是心理問題。
當我自己開始編寫程序之後,測試提出的一些問題也讓我覺得:我竟然犯了這樣明顯的錯誤。再後來看了一本書叫《看不見的大猩猩》,人的精力是有限的,當放在自認為更重要的事情上時,就很容易忽略別人看起來很明顯的存在。這不是主觀故意的忽視,而是客觀存在的科學。當然也不排除某些同事確實存在偷懶的情況,沒有完成開發測試。

原則 9:程序某部分存在更多錯誤的可能性,與該部分已發現錯誤的數目成正比。

直白點說,就是如果一個模塊已經發現的 bug 數量明顯多於其他模塊,那麼未來在這個模塊發現 bug 的可能性仍然很高。
測試用例的設計也應該有所側重,對已有 bug 數多的部分進行額外的測試。

原則 10:軟件測試是一項極富創造性、極具智力挑戰性的工作。

大家傾向於認為在項目團隊中最重要的是開發人員,其他崗位都是輔助性工作,但從市場營銷的角度來說,團隊中的每個位置都至關重要。
區別只在於所做工作對實現目標的重要性和可替代性,優秀的測試的重要程度並不亞於程序員。不管什麼崗位,都需要不斷的學習提升通用技能和專業能力。如果自己都不認同所在崗位存在的價值,認為無需努力提升自己,那不管在什麼崗位都會被時代所淘汰。

2.4 小結

三個重要的測試原則:

• 軟件測試是為發現錯誤而執行程序的過程。

• 一個好的測試用例具有較高的發現某個尚未發現的錯誤的可能性。

• 一個成功的測試用例能夠發現某個尚未發現的錯誤。