Bug系列

 
Bug系列
 

2009-11-19 作者:吳朝東 來源:吳朝東的BLOG

 

Bug之一——bug的前世今生

Bug這個名詞已經很老了,從網絡上查到的資料:

>>>>>>

1946年,Grace Hopper在發生故障的MarkⅡ計算機的繼電器觸點裏,找到了一隻被夾扁的小飛蛾,正是這隻小蟲子“卡”住了機器的運行。Hopper順手將飛蛾夾 在工作筆記裏,並詼諧地把程序故障稱爲“bug”。bug的意思是“臭蟲”,而這一奇怪的稱呼,後來演變成計算機行業的專業術語。雖然現代電腦再也不可能 夾扁任何飛蛾,大家還是習慣地把排除程序故障叫做Debug(除蟲)。

<<<<<<

關於Grace Hopper其人,參見http://en.wikipedia.org/wiki/Grace_Hopper,上面有這位美女強人的照片和史上第一隻(個)bug的照片以及生平介紹。

關於bug最出名的事件就是“千年蟲問題”了,關於損失最慘重的bug,目前有導致28位“自己人”被炸死的愛國者導彈事件,還有其他諸如火箭發射失敗等等,這些是目前爲止有關bug最慘痛的記憶了,至於以後會不會有更慘重的,可能吧。計算機是萬能的,因此計算機裏面的bug也是萬能的,相信我吧。不信的話你可以看看《戰爭遊戲》,總共兩部,看看之後你就會知道計算機在某種情況下是可以毀滅人類的,當你看完之後如果驚出一身冷汗,記得提醒自己幸好是電影~~

最近關於bug的消息也不少,IE有個bug不是藏了好多年最近被人給挖出來了麼。下面是添油加醋過的報道截屏:

看着那個“全球新的災難”,是不是覺得很遙遠啊。

看吧,bug多厲害啊,作爲bug獵手的測試人員,是不是覺得特有自豪感,覺得自己的職業特偉大~~ 先別太激動,因爲下一篇我將要結合經驗講一些關於什麼是bug話題。

Bug之二——“廬山真面目”

在介紹bug的光輝歷史的時候,不經意間給bug蒙上了一層神祕的面紗,彷彿bug是一個遙遠的神祕的事物,如同金字塔之中的種種。其實bug本身並沒有那麼神祕。

首先給出一個“官方”的定義,來自Ron Patton《軟件測試》:

>>>>>>

至少滿足下列五個規則之一才稱發生了一個軟件缺陷(Software bug):

1) 軟件未實現產品說明書要求的功能

2) 軟件中出現了產品說明書中指明不應該出現的錯誤

3) 軟件實現了產品說明書未提到的功能

4) 軟件未實現產品說明書雖未明確提及但應該實現的目標

5) 軟件難以理解、不易使用、運行緩慢或者——從測試人員的角度看——最終用戶會認爲不好

<<<<<<

關於上面的“官方”解釋我就不做贅言了,“照搬”是沒有意義的,所以如果需要了解更多,請閱讀原書《軟件測試》(Ron Patton)著。從我自己的經驗來看,所謂bug,大致可以分爲“該做的沒做,做了不該做的,沒有按要求做”,我自己就是這樣簡單的來對bug做出分類。

所謂“該做的沒做”的又包含了三個部分,即

  • 產品說明書中要求做的沒做
  • 產品說明書中沒有明確要求(單獨作爲項目列出)但是應該實現的
  • 產品說明書中沒提到,但是測試人員認爲應該做的

對於上面的“該做的沒做”三種情況應該區別對待,對於第一種就很直接了,產品說明書中列出來的功能沒有實現,直接作爲bug提交了;第二種稍微麻煩一點,需要跟開發人員統一認識;第三種就更加麻煩了,這時候需要開發人員項目經理測試人員一起合計合計了,統一認識之後再決定怎麼處置這個bug。

所謂“做了不該做的”,這句話是作爲測試新人和開發人員來講最難理解的bug,這裏並不是指它的概念或者意義等理性可以解決的事情,而是感性層面的“理解”。試想開發人員好不容易做了一個新功能,測試人員卻拿着“產品說明書”這根雞毛當令箭來要求刪除,大多數人可能會想到,額外的功能總是好的……但是,需要提醒的是,每一個額外的功能都有引入額外的bug的風險,這不僅僅增加了測試的工作量也增加了產品的質量風險,更重要的是,增加的額外功能的合理性是否確定。比如我們開發一個課程管理系統,一般情況下產品說明書中要求給普通用戶的功能只有登陸和瀏覽,這個時候如果開發人員提供了其他額外的功能如搜索,排序甚至編輯,這就會出現問題了,這些額外的額操作會額外增加系統或者服務器端的負擔,甚至具有安全問題。當然,對於“做了不該做的”類型的問題,需要找到相關開發人員與PM一起確定,測試人員是不應該自以爲是地作爲bug提交,至於原因,在後續的文章中會提到。

所謂“沒有按要求做”,這裏的要求是指“應該做成什麼樣子”,這些內容是依據產品說明書來定的,比如一個“職位”選項,產品說明書中明確指出使用“下拉框”來處理,而開發人員偏偏使用了“文本框”,這些都是bug。對於這種類型的bug,辨別和處理相對就比較簡單了,而且我們找到的大部分bug也都是這種類型。

關於bug的定義,其實直到現在都沒有“官方定義”,這也爲什麼我引用Ron Patton的話的時候使用的是“‘官方’定義”的原因了。上面提到bug的時候,總是帶着一個親屬“產品說明書”,實際上在當前中國很多軟件項目中並沒有這個東西,因此在項目實踐過程中,上面提到的內容千萬不要生搬硬套,至於怎樣靈活處理,在後續文章中也將提到個人見解。

Bug之三——“自定義”bug

所謂“自定義”是指針對於當前很多軟件項目中沒有“產品說明書”或者沒有合格的“產品說明書”這類現實主義情形而言的。

在上一篇文章中介紹了bug的“官方”定義和個人見解,其中涉及到了“產品說明書”這個對於當前一些軟件項目而言尚屬理想主義產物的東西,在這篇文章中,我分享給大家的就是我之前所經歷的一個類似的項目經歷,當然也要獻給大家一些我的“偏方”。

對於同一個問題,不同的人會有不同的看法,“一千個觀衆眼中有一千個哈姆萊特”就是這個意思。這句話用來形容開發人員和測試人員對於bug的態度就更加貼切了。很多的時候,當測試人員發現並提交了一個bug之後,得到的開發人員的迴應是“This is not a bug”(這不是一個bug)或者“這不是一個嚴重的bug”之類,我第一次聽到這句話的時候心情是相當沮喪,進而轉化爲憤怒。

沒有“產品說明書”,憑什麼這是bug?這的確是個問題。問題生來就是被解決的,所以我們一定治得了它。最直接最天真的想法可能就是建立起一套完善的機制,有了產品說明書不久結了麼。果真是個好辦法,可是太理想主義了,這就如同老鼠掛鈴鐺故事中的那一羣老鼠一樣,辦法是很好,但是卻無法實施或者很難實施。一套合理的軟件流程不是朝夕之間的事情,更何況一套完善的機制也不可能完全杜絕未定義bug。怎麼辦呢?另一種辦法來了:有事好商量唄。

在進行討論之前,測試人員還是有些準備工作要做的。對於“bug”這種罪大惡極的東東,我們應該列舉其罪證。這個時候可能拿着《軟件測試》上面的東西來解釋就顯得有些蒼白無力,這畢竟是測試人員的“聖經”卻不是開發人員的。誇張點就像兩種信奉不同宗教的人一樣,可以說是一個信奉上帝,一個信奉阿拉,你叫人家阿拉伯人跟着美國人信奉基督教,那顯得有點過分了吧。更何況“聖經”上面講的東西也是泛泛而談,並沒有嚴格指出bug到底長什麼樣子。這個時候更加合理的辦法是列出自己的考慮的點,也有更有說服力的做法——找一些可以印證自己看法的知名軟件產品中相同或者相似功能點,在這一方面“微軟”可幫了不少“忙”。

開始討論了,雙方本着實事求是的態度來討論這是不是一個bug,這就如同一場法庭辯論。測試人員作爲原告代理律師,開發人員作爲被告代理律師,項目經理作爲法官。記住,我們只是律師來的,所以宣判的結果並不會直接影響到我們,因此測試人員千萬不要把自己當成原告,開發人員也不要把自己當成被告他爸(實際情況卻經常這樣,測試人員把bug當作自己的戰利品,而那可是開發人員辛辛苦苦創造出來的軟件啊),我們應該以理性的態度來審視這個待定的“bug”。開庭之後,原告代理律師陳述己方觀點,接着被告代理律師陳述,然後雙方進行短暫的和平而友好的辯論,然後宣判,不準上訴。

當然還需要注意的是,這個會議儘量不要佔用大家太多的時間,也沒有必要十分正式的邀請一大幫人來開會,但是開會完畢之後,測試開發雙方要無條件接受討論結果並及時進行相關的處理。

筆者經歷的項目中,很多時候都是測試人員取得了最終的勝利,這倒不是因爲筆者強勢或者咄咄逼人,更多的時候我拿出相關著名軟件的例子之後並陳述爲什麼應該這樣做之後,開發人員便接受了這樣的解釋。當然,有時候也是測試人員不瞭解軟件產品相關領域知識而導致了誤報bug,這個時侯測試人員應該心悅誠服地接受“This is not a bug”,這個時候任何多餘的動作或者言語都是無效的,不僅不會給自己帶來什麼好處,也會給項目組帶來不和諧的因素。在全民建設社會主義和諧社會的年代,大家都要和諧~

Bug之四——好心辦壞事?

“做了不該做的”bug,到底是是測試人員“狗咬呂洞賓不識好人心”還是開發人員真的“好心辦了壞事”?用當今最流行的話來說,這的確是一個“糾結”的問題。

這兩種情形在實際的測試活動中都會存在,有些時候的確是測試人員急功近利或者太死板,險些扼殺了一個很好的idea;有些時候確實又是開發人員因爲這種或者那種原因,別出心裁卻導致了畫蛇添足。

還是前面的觀點,問題生來就是被解決的,只是這個問題稍微顯得麻煩了一點而已,處理起來比較棘手,稍有不慎就會得罪開發人員或者測試人員中的某一方。這個問題和上一篇文章中提到的“自定義”bug其實是一個問題,即開發人員與測試人員的關係的問題。

測試理論中經常出現的其他學科術語莫過於“經濟學”“心理學”(如在測試結束標準中考慮到的“測試經濟學”),“心理學”範疇主要討論的就是測試人員與開發人員之間的關係處理問題。一個比較流行的說法稱開發人員是創造者,而測試人員毀滅者,肆無忌憚的破壞者,筆者是很贊同這種說法和做法的,但是僅限於在測試技術本身,而不包括測試整個過程。作爲人來講,人都有惰性,人都有好勝心,人都有各種各樣正常的不正常的自尊心,這纔是問題的癥結所在。

測試人員A發現了一個“做了不該做的”bug,這時候多多少少有了一點點炫耀的虛榮心,一點點自豪感,然後這個時候他興沖沖找到相關開發人員B告訴他“你這個功能是畫蛇添足的”,這個時候引來的是開發人員的反抗,這是因爲一個bug意味着他要做額外的工作了(與人的惰性相斥),另外被人說自己寫出來的代碼有問題會不經意間傷及他的自尊心,然後B開始爲自己辯解,雙方互不相讓(這是好勝心在作祟,當然也包括自尊心等等因素),事情開始變得糟糕了。

解決辦法其實說起來很簡單,引用某部影片(《十全九美》)裏面的那句臺詞——“淡定”。大家都應該淡定,在遇到說不清的bug,在雙方都認爲自己對的時候,要保持淡定。問題需要理性的解決,而不是因爲感性的因素而互不相讓,這樣對於問題的解決沒有任何幫助。筆者不提倡有些哲人提出的“別人打了你一耳光,那把另外一面連伸過去讓他打”這種“高風亮節”,筆者推崇的是理性解決問題。對方能否保持理性的態度來解決問題那是對方的問題,作爲我們測試人員自己,要保持淡定。找到了bug,“勝不驕”溫和提醒開發人員並提出自己的看法或者推薦的解決方案;當遇到被打回的“bug”,“敗不餒”鎮定分析被打回的原因,如果必要可以“Reactive”並再次向相關人員解釋自己的看法。遇到溫和的同事,要淡定,不能一副潑婦的模樣去“欺壓”良民,欺負老實人不算真本事;遇到脾氣急躁的同事,要淡定,耐心說,實在擺不平,找上級,“官大一級壓死人”,這是下下策,因爲常用這一招會讓人覺得你這人總愛“打小報告”,會被同事疏遠的。

專門寫這些東西出來,本身與測試技術沒多大幹系,但是卻與測試工作的能否順利息息相關。筆者曾經帶過一個新人,因爲類似的原因導致了其離開,因此一直深感遺憾,這纔想起把自己的一套“餿主意”拿來分享,希望對遇到類似情況的同行有所幫助。

Bug之五——Bug Report

在前面的四篇文章泛泛而談bug相關的一些問題,只能遲到這篇文章中開始介紹bug本身相關比較實用的知識。先從bug報告開始,Bug報告的洋名似乎比中文名來的順耳——Bug Report。

一般意義上的bug Report即是將所發現的bug整理歸納起來,隨着缺陷管理工具的盛行,這種報告類型的報告已經漸漸失去了意義,但是筆者還是要從這種類型的bug report談起——一開始,我們先來了解一下單個bug的組成要素。先來看一個bug的簡單示例:

Bug ID

Bug 783

標題

編輯用戶信息功能 “用戶職位”字段未保存

狀態

Active

原因

New

嚴重級別

2

描述

[Test Cases]

AAA_UserProfile_0003

 [Precondition]

<在此填寫預置條件>

[Descrīption]

<在此填寫詳細描述信息>

[Expected]

<在此填寫期望結果>

[Actual]

<在此填寫實際結果>

上表中並不是一個完整的bug的實例,但是基本上已經囊括了bug的基本要素。對於這些基本要素,接下來作簡要說明:

1. Bug ID是bug的唯一標識符,類似於公民身份證號碼,每個bug有且僅有唯一的一個ID序號。如: 示例中的“Bug 783”

2. 標題 是對bug的一個簡要概括。如: 示例中 編輯用戶信息功能 “用戶職位”字段未保存

3. 狀態 是指bug當前所處的狀態。如:示例中 Active是指bug現在是活動的,即沒有尚未被開發人員修復。bug的狀態一般分爲三種,即Active, Resolved, Closed,分別對應於活動的(開發人員未解決掉的),被解決的(開發人員聲明已解決但尚未通過迴歸測試驗證的),關閉的(已經被開發人員修復並通過迴歸測試的)。關於bug的三種狀態的轉換將在後續文章中專門討論。

4. 原因 是指將bug調整到某個狀態的原因。如:示例中的New是指測試者新發現了一個bug,所以把狀態調整爲Active。Bug狀態調整可能有多種原因,即使是對於同一個狀態在不同的情況下也會有不同的原因。關於這部分的討論也將在後續文章中提出。

5. 指派給 是指將bug指派給對應的負責人進行處理。如:實例中的 Q Chen是指項目相關人員處理bug之後將bug提供給下一步處理人員Q Chen。對於指派給的具體人選,不同的bug狀態下有不同的要求:測試人員測試發現的bug指派給開發相關模塊的開發人員或者開發組負責bug處理的人員,開發組處理後的bug會指派給發現bug的測試人員。

6. 優先級 目前在測試組實際工作中使用時同時包含有嚴重級別的意義,嚴重級別是指bug對應用程序或者操作系統的影響程度,嚴重界別越高的bug等待解決的優先級越高。如: 實例中的 1是指優先級(嚴重級別)最高的一類bug,這類bug需要儘快解決掉。關於Bug的優先級劃分將在本系列文章中的後續篇章專門討論。

7. 描述 部分是bug提交中最重要的部分,是對bug信息的一個詳細的描述。如: 示例中 [Test Cases] APS_SheetJop_0003 ……我們可以發現“描述”被劃分爲幾個子模塊,以詳細且清晰地描述bug相關的信息,以便bug相關人員處理bug和其他人員瞭解bug的各個階段的各類信息。在下一篇文章中我們將詳細討論“描述”中的內容。

Bug之六——斑斑“罪證”

在上一篇文章中給出bug的一個示例,簡單介紹了bug自身的一些常用屬性,如Bug ID、狀態、原因、指派給等。按照約定,這篇文章將介紹bug重現的問題,亦即bug示例中的“描述”部分。

細心的讀者會發現,在上面的bug“描述”一欄中又增加了幾個用方括號標記起來的標記,這是筆者在管理的過程中添加進去的幾個標籤。一個完整的bug描述如下:

描述

[Test Cases]

<出現該bug的測試用例的ID>

 [Precondition]

<在此填寫預置條件>

[Descrīption]

<在此填寫詳細描述信息>

[Expected]

<在此填寫期望結果>

[Actual]

<在此填寫實際結果>

[Found in Build]

<發現bug的源代碼build>

[Reason]

<bug產生的原因,開發人員填寫>

[Solution]

<解決bug的方法>

[Resolved in Build]

<解決bug的源代碼Build號,開發人員填寫>

[Reopen Reason]

<可選,bug被重新激活的原因>

關於描述的信息在上面的表格上面基本上已經列出來了,因此不必要再一一詳述。筆者在實踐中即是按照該模式來管理bug的,只要“描述”得當,我們完全可以僅依照這部分的內容就把bug重現出來。當然,有些地方還是有必要解釋一下:

1 [Test Cases][Precondition][Descrīption][Expected][Actual][Found in Build]這些標籤是由測試人員(嚴格意義上是bug提交人員,如果可能的話可以要求所有的bug提交者都遵循這種模式以便於管理)添加並填寫的,而[Reason][Solution][Resolved in Build]這些標籤是由開發人員(bug的修正人員)填寫的。

2 有關測試環境的內容不列入單個bug的report中,對於其他僅在少數用例中使用的環境則在預置條件即“[Precondition]”中加以描述。

3 [Reopen Reason]是指測試人員發現不過沒有被修改但是已經被開發人員標記爲修改的bug或者已經被關閉的bug死灰復燃,這個時候測試人員需要重新激活該bug,因此除了需要註明重新打開的原因之外,一般還需要在其中添加如諸如Build版本信息等內容。

4 當一個bug被重新激活之後,一個bug進入一個新的生病週期,這在bug的描述中體現爲[Reopen Reason]標籤之後會跟着出現[Reason][Solution][Resolved in Build]等有開發人員填寫的標籤以描述bug的修正情況。

5 [Resolved in Build]中的內容一般形式上寫爲版本號加上一個“+”表示該版本及以後的版本中該bug都不會被重現了。如SystemA1.0.1320+

Bug之七——優先級

Bug的優先級是bug管理過程中必須考慮的問題。對於優先級的劃分,不同的軟件公司有自身的一套制度,因此筆者介紹的也僅僅是自己比較喜歡的一種方式。

爲了便於bug的提交和管理,也爲了方便於與開發人員進行交流,筆者傾向於在項目中將bug劃分爲三個等級,而不是網絡上流傳的五等級版本甚至七等級版本(在成熟的軟件組織中,使用更細的bug等級劃分有利於bug分類,質量評審等工作的順利進行)。這三個優先級分別即優先級1(嚴重的),優先級2(比較嚴重的)和優先級3(一般的)。

筆者劃分bug等級的指導思想很簡單,嚴重影響測試執行的bug是最嚴重的,即優先級1 的bug,除此之外所有導致應用程序崩潰掉的bug也列入到優先級1中;其他功能性bug列入比較嚴重的bug的隊伍,即優先級2;界面上的bug列爲一般的,即優先級3。

作者在實踐過程中推行的就是這種bug分級制度。這種分級制度看起來過於主觀,而不像網絡上流傳的各個bug優先級劃分的版本中,將每個優先級的bug的表現都一五一十列出來,如下是筆者以前使用到一個bug優先級劃分文檔中列出的優先級1的bug特徵:

a) 應用程序某個模塊功能未實現(包括整個模塊不能運行)

b) 用戶的信息被破壞或者丟失

c) 可重現的不可避免的崩潰,死鎖

d) 功能和性能急劇衰退

e) 嚴重的內存泄漏

f) 導致功能無法正常使用的UI設計(UI響應遲緩)

g) 其他

的確,這些bug優先級劃分很明確,讓人一目瞭然並且覺得很有道理,可是拿到實際中一用,麻煩開始來了。因爲某些描述仍然不夠詳細,含混不清的描述諸如“功能和性能急劇衰退”,碰到這種描述,不同的人會有不同的理解,而不同的理解必然會帶來各種各樣的問題。因此,筆者在實踐中逐漸摒棄了這種做法(當然,筆者並不排除將來可能還是會回到一些比較正規的管理方法上來,但是目前這種“標準”方法並不適合筆者所在的公司~),並開始逐步推廣筆者自己剛纔提到的粗放式bug優先級劃分方法。

對於該劃分方法,筆者還需要進一步的說明。筆者剛纔提到的“嚴重影響測試執行的bug”其實也是指系統的基本功能或者核心功能,比如新建編輯刪除功能中,對於同樣是信息爲保存到數據庫——即新建後記錄未添加到數據庫,編輯後記錄未更新,刪除後數據仍然存在於數據庫中——這時候筆者僅僅將新建功能的該bug置於優先級1中,編輯刪除bug則置於優先級2中。這種方法與很多正統的方法很不一致,因爲在很多劃分方法中“信息未保存”都是優先級1的bug。但是筆者自認爲這樣做是有理由的:當新建功能發生該類型bug而編輯刪除功能正常時,編輯刪除功能仍然無法測試或者實現(因爲沒有數據啊),這在客戶的江渡看來會直接視爲新建編輯刪除功能均未實現。新建功能正常而編輯或者刪除功能失效,則不會影響到其他功能的使用(當僅編輯功能失效的時候,新建和刪除功能並不會受到影響),測試人員仍然進行新建刪除功能的功能測試,客戶依然可以使用新建和刪除功能。

當然,筆者使用上面的劃分方式還有其他的原因——基於bug管理和測試開發工作的順利推進。讀者可能會注意到,使用上面的bug劃分方式會減少優先級1的bug的數量,筆者這樣做是因爲筆者在bug管理中推介的方式是優先級1的bug不允許推遲到下一個工作日修改。試想,如果優先級1的bug的數量如果過多自然會導致這種管理方式推行的極大阻力——沒有哪個開發人員會喜歡讓自己一整天的時間花費在修復bug上。當我們提交的優先級1的bug都是非常緊急的,會影響到開發或者測試的進度的話,開發人員就自知理虧不得不去修復這些bug了,這就保證了即使到了項目很急迫的時間,我們項目的主體功能還是穩定可用的,並有效遏制了嚴重bug的生存期。

對於優先級2與優先級3 的劃分點,只是筆者個人看法,因爲筆者目前所經歷的項目都是功能性爲主,因此對於UI相關的要求相對較低,因此筆者採取了這種粗放的方式(將UI相關bug歸納爲優先級3,其他的非UI的非優先級1的bug全部塞到優先級2 的集裝箱中~)。

Bug之八——bug的生命週期

Bug的生命週期是bug管理中另外一個需要事先規範的管理點。

所謂的bug的生命週期,筆者將其簡單的理解爲bug狀態在什麼時候怎樣轉換,基於什麼原因轉換。一般我們將bug的狀態劃分爲三種,即活動的,已解決的,已關閉的。活動的即尚未被修復(處理)的bug,已解決的即開發人員對bug進行了處理(包括修復,或者標記爲延期處理等)但是尚未得到測試人員對處理進行驗證的bug。

在介紹bug生命週期的時候,大多數作者都習慣於拿出一副生命週期轉換圖,筆者亦不能免“俗”~

上圖是一個簡化了的bug生命週期管理,覆蓋了日常工作中常見的bug的管理機制,關於bug的生命週期的管理,還有一些注意事項:

  • Bug包括三種存在狀態,即Active,Resolved和Closed。
  • 任何一個bug的狀態在任意時刻都屬於且僅屬於三者中的某一種。
  • 在bug的整個生命週期中,有且僅有一次機會被標記成Closed。
  • 在bug被標記成Closed的同時,也標誌着整個bug生命週期的結束。
  • 只有測試人員有權限將bug狀態更改爲Closed。
  • 不得將bug的狀態直接由Active更改爲Closed。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章