# Bug跟蹤
Bug跟蹤是一個寬泛的話題;貫穿本書會討論此問題的各個方面。盡管這里我們要著重于配置和技術因素,但是首先要從一個策略問題開始:Bug跟蹤系統中應該包含哪些信息?
術語*Bug跟蹤*很有誤導性。Bug跟蹤系統也通常會用來跟蹤哪些初始與結束狀態不同,包含可選的中間狀態,并在生命周期中積累信息的問題,例如新特性請求、一次性任務以及被動性的補丁。由于這些原因,Bug跟蹤也被稱為*問題跟蹤(issuetrackers)*、*缺陷跟蹤(defect trackers)*、*制品跟蹤(artifact trackers)*、*請求跟蹤(requesttrackers)*以及*問題票跟蹤(trouble ticket systems)*。[Appendix?B, *自由Bug跟蹤系統*](# "Appendix?B.?自由Bug跟蹤系統")包含了一個此類軟件的列表。
在本書中,我會繼續使用“Bug跟蹤(bug tracker)”這個名稱,因為大多數人這樣稱呼,但我會使用*問題(issue)*來稱呼Bug跟蹤數據庫中的單個條目。這讓我們可以把用戶遇到的(Bug本身)正常或不良行為與跟蹤系統中Bug的發現、診斷和最終解決的*記錄*區分開來。請牢記,盡管大多數問題與實際的Bug相關,我們也可以用其來跟蹤其它類型的任務。
典型的問題生命周期如下:
1.
某人發起了一個問題。他提供了摘要,初始描述(如果合適則包含重現方法;如何激勵好的Bug報告請看[Chapter?8, *管理志愿者*](# "Chapter?8.?管理志愿者")的[the section called “將每個用戶當作潛在的志愿者”](# "將每個用戶當作潛在的志愿者")),以及其它跟蹤系統要求的信息。項目可能對發起人一無所知—Bug報告和特性請求既可能來自用戶社區,也可能來自開發者。
一旦發起,這個問題就進入了*打開(open)*狀態。因為還沒有作出任何行動,一些跟蹤系統也將其標示為*未驗證(unverified)*或*未開始(unstarted)*。它還沒有分配給任何人;或者在某些系統中將起分配給一個冒牌用戶來表示其還沒有真正的分配。此刻,它存在于一個保留區:這個問題已經記錄,但是還沒有成為項目關注的一部分。
1.
其他人讀到這個問題,并做出回復,或許會再向發起者詢問來澄清一些問題。
1.
Bug得到*重現(reproduced)*。這可能是其生命周期中最重要的一個時刻。盡管bug還沒有修正,但發起者之外的人重現這個事實可以證明這個bug的真實性,此外,可以確認原發起者通過報告真實的bug為項目做出了貢獻。
1.
Bug得到*診斷(diagnosed)*:它的原因得到確認,如果可能,會對修正這個bug所需的工作量做出評估。請確認這些內容會在問題中得到記錄;如果診斷人要離開項目一會兒(對于志愿開發者這很普遍),其他人應該能夠接手。
在本階段,或者前一個階段,開發者可以“獲取”問題所有權并將其*分配(assign)*給自己([Chapter?8, *管理志愿者*](# "Chapter?8.?管理志愿者")的[the section called “明確區分調查和指派”](# "明確區分調查和指派")詳細描述了分配過程的細節)。問題*優先級(priority)*也可以在本階段設置。例如,如果某個問題嚴重到足以影響下一個版本的及時發布,則需要盡早標示出來,跟蹤系統必須能夠使其突出顯示。
1.
問題納入解決的日程(schedule)。納入日程并不是意味著規定一個解決的日期。有時候只是決定未來的那個版本(下一個版本不是必須的)必須解決這個bug,或者這個bug將會阻礙哪些特定版本。如果很容易修正,也可以取消納入日程這一步。
1.
Bug得到修正(任務完成、或應用了補丁、或者其他類似的事情)。變更或者變更集必須記錄在問題的回復中,其后是問題被標注為*解決(resolved)*而得到*關閉(closed)*。
這個生命周期有許多變種。有時候一個問題再發起之后很快就會關閉,例如發現它不是一個bug,而只是部分用戶的誤解。隨著項目獲得了越來越多的用戶,就會帶來更多無效的問題,開發者會用日益缺乏耐心的回應來關閉這些問題。要嘗試預防這后一種趨勢。這對誰都沒有好處,每個案例中的每個單獨用戶對于此前的無效問題沒有任何責任;統計學的趨勢只是從開發者而不是用戶的視點有效。 (在本章后的[the section called “Bug跟蹤的預過濾”](# "Bug跟蹤的預過濾")將會看到減少這種無效問題的技巧。)另外,如果不同的用戶反復經歷同樣的誤解,這或許意味著軟件的某方面需要重新設計。如果有一個問題經理監視著bug數據庫,就會很容易發現這種模式;見[Chapter?8, *管理志愿者*](# "Chapter?8.?管理志愿者")的[the section called “問題管理員”](# "問題管理員")。
生命周期的另一種常見變種是問題在步驟1之后直接以*重復(duplicate)*狀態關閉,重復是某人發起了一個項目已知的問題。重復不僅限于開放的問題:它也可能來自已經修正的bug重現(這個稱為*衰退(regression)*),無論何種情況最佳的解決方式是重新打開最初的問題,并將新的報告復制到最初的問題中。Bug跟蹤系統應當能夠雙向保持聯系,這樣重復的重現信息中就可以在原問題中看到,反之亦然。
開發者關閉這個問題的第三種情況是他們認為已經修正了問題,只是讓原報告者拒絕這個修正并重新打開它。這通常僅僅是因為開發者不能訪問重現bug的環境,或者因為他們不能通過報告者的再現描述測試這個修正。
除了這些情況,不同的跟蹤軟件也有一些其它小的生命周期細節。但基本的生命周期是相同的,生命周期本身并不特定于開源軟件,只是暗示了開源項目如何使用他們的bug跟蹤系統。
就像步驟1暗示的,跟蹤系統和郵件列表或網頁一樣,是項目的門面。任何人可以發起一個問題,任何人可以瀏覽當前打開的問題列表。由此我們也能推斷我們無法知道有多少人在等待給定問題的進展。而開發社區的規模和技巧限制了問題解決的速率,項目至少應該知道每個出現的問題。即使問題會緩慢小時,一個回復也會鼓勵報告者保持參與,因為她能感覺到有人已經為其所作的事情登記(請牢記填寫一份問題遠比發一封郵件更麻煩)。此外,一旦開發者看到一個問題,它就進入了項目的意識中,也就是開發者會查看此問題的類似情況,或者會與其他開發者討論,等等。
及時反應的需求意味著兩件事:
-
跟蹤系統必須能夠連接到郵件列表,這樣問題的每個變更,包括初始的填寫,都會導致描述發生情況的郵件。這些郵件列表通常與正規的開發列表不同,因為不是所有的開發者會希望接收自動bug郵件,但是(就像提交郵件)Reply-to頭應該設置為開發郵件列表。
-
填寫問題的表單一定能夠捕捉開發者的郵件地址,這樣她可以聯系到更多信息。 (然而,它不應當*要求*輸入報告者的郵件地址,因為一些人喜歡匿名報告問題。匿名訪問的重要性可以看本章后面的[the section called “匿名和參與”](# "匿名和參與")。)
### 與郵件列表交互
請確保bug跟蹤系統不會成為討論論壇。盡管讓人參與bug跟蹤很重要,但從根本上它不適合實時討論。更應該將其當作歸檔,組織證據和其他討論(通常發生在郵件列表)的引用。
做出這種區別有兩個原因。首先,Bug跟蹤系統的使用比郵件列表(或者實時討論論壇)更加笨拙。這不是因為bug跟蹤系統都沒有好的用戶界面設計,而是因為它們的界面設計用來捕捉和展示分離的狀態,而不是自由流動的討論。第二,不是每個參與到特定問題討論的人都必須注意bug跟蹤系統。優良的問題管理(見[Chapter?8, *管理志愿者*](# "Chapter?8.?管理志愿者")的[the section called “像分擔技術任務一樣分擔管理任務”](# "像分擔技術任務一樣分擔管理任務"))是讓每個問題被恰當的人注意到,而不是讓所有的開發者監視所有的問題。在[Chapter?6, *交流*](# "Chapter?6.?交流")的[the section called “Bug跟蹤系統中無對話”](# "Bug跟蹤系統中無對話"),我們會關注確保人們不會脫離合適的論壇而陷入在bug跟蹤系統內討論的問題。
有一些bug跟蹤系統可以監控郵件列表并自動記錄關于已知問題的郵件。他們通常是通過在郵件列表中,將郵件標題出現的問題標示號碼作為特殊字符串來識別問題;開發者學著在他們的郵件中包含這類字符串來觸動跟蹤系統的注意。Bug跟蹤系統可以保存整個郵件,或(更好一點)只是記錄郵件在郵件列表歸檔中的鏈接。無論何種方式,這是一個非常有用的特性;如果你的跟蹤系統有這個功能,要確保在開啟它的同時提醒人們利用這個特性。
### Bug跟蹤的預過濾
大多數問題數據庫最終會遭遇相同的困境:由好心但沒經驗或消息不靈通用戶所發起的重復和無效問題的洪流。與這種趨勢斗爭的第一步通常是在bug跟蹤系統的前頁放置一個顯著的提醒,解釋如何知道一個bug是否確實是bug、如何查找bug是否已經被發起、以及如果依然認為是新bug時如何有效的報告。
這會暫時減少噪音,但是當用戶數增加后,問題還是會出現。每個單獨的用戶都不應該因此被譴責。即使他們的第一個bug報告沒有用處,你還是要鼓勵他們保持參與并在以后提出更好的問題。同時,項目需要保持問題數據庫的垃圾越少越好。
這兩件事可以最大程度的防止這些問題:請確認監視bug跟蹤系統的人有足夠的知識,能在問題無效或重復時關閉它,而且能夠要求(或強烈的鼓勵)用戶在填入跟蹤系統前確認他們的bug。
第一種技術看起來被廣泛使用。即使項目有巨大的問題數據庫(例如,Debian在[http://bugs.debian.org/](http://bugs.debian.org/)的bug跟蹤系統,目前有315,929個問題)也是這樣安排的,這樣*某人*進入時就能看到所有的問題。不同的問題類別可能是不同的人。例如,Debian項目包含了一組軟件包,這樣Debian就能夠自動路由每個問題到合適的包維護者。當然,用戶有時會把問題類別搞錯,這樣一開始問題就會發送到錯誤的人,而他可以再將其轉向到其他人。然而,最重要的事情是負擔被分擔了—無論用戶在填寫的時候是對是錯,問題監視的任務還是會在開發者之間分配,所以每個問題都能夠得到及時的回復。
第二種技術應用的沒有那么廣泛,可能因為它很難被自動化。本質思想是每個新問題都是經過伙伴處理后進入到的數據庫中。當用戶認為他發現了一個問題,他就會被要求在郵件列表或IRC頻道中對其進行描述,然后得到某個人對其是bug確認。盡早引入第二雙眼睛可以防止許多虛假的報告。有時候第二方可以識別出這個行為不是一個bug,或者已經在最近的發布中被修正。或者她可能由于類似癥狀bug而感到熟悉,而且可以通過給用戶指明老的問題來防止重復的填寫。通常僅僅是詢問用戶“你查找過bug跟蹤系統以確定這個問題是否已經報告過了嗎?”許多用戶不會想到這個一點,如果有人*期望*,你可以愉快的為他們查找一下。
這種伙伴系統確實可以保證問題數據庫的清潔,但是也有一些不利的地方。許多用戶無論如何也要獨立發起問題,對為發起新問題而尋找伙伴的指南看不到或者視而不見。因此,還是需要有志愿者關注問題數據庫。此外,因為許多新報告者不理解維護問題數據庫的難度,對他們忽略指南的行為進行過于嚴厲的斥責是不公平的。所以志愿者必須保持警覺,聯系如何反彈未經搭檔處理的問題給報告者。目標是訓練每個報告者在未來使用伙伴系統,這樣就有一個日益增長的能夠理解問題過濾系統的用戶池。當看到一個未經伙伴系統處理的問題時,理想的步驟是:
1.
立刻回復問題,禮貌的感謝用戶的填寫,但是向他們指出伙伴系統的操作指南(當然應該在網站的顯著位置)。
1.
如果問題是明顯有效而且沒有重復,想辦法證明它,使之開始正常的生命周期。畢竟,報告者沒有被告知伙伴系統,所有浪費工作量關閉有效的問題是沒有意義的。
1.
否則,如果問題不是很清楚的有效,關閉它,但是要求報告者在得到伙伴的確認后重新打開它。當他們這樣做時,他們應當放置一個確認郵件列表線索的引用(例如一個郵件列表歸檔的URL)。
請記住盡管系統會逐漸改善問題數據庫的信/噪比,但是不會阻止誤填的發生。完全防止誤填的唯一方法是關閉bug跟蹤系統,只開放給開發者—治愈幾乎永遠比疾病本身更壞。應當接受無效問題的清理是項目日常維護的一部分,并努力得到更多的人們來幫忙。
在[Chapter?8, *管理志愿者*](# "Chapter?8.?管理志愿者")的[the section called “問題管理員”](# "問題管理員")也有介紹。
- 前言
- 為什么寫這本書?
- 誰應該讀本書?
- 資料來源
- 致謝
- 免責聲明
- 1. 介紹
- 歷史
- 現狀
- 2. 起步
- 從你擁有的開始
- 選擇許可證并應用
- 設置風格
- 通告
- 3. 技術基礎設施
- 一個項目需要什么
- 郵件列表
- 版本控制
- Bug跟蹤
- IRC / 實時聊天系統
- RSS供稿
- Wikis
- 網站
- 4. 社會和政治的基礎架構
- 慈善獨裁者
- 共識為基礎的民主(Consensus-based Democracy)
- 寫下所有的內容
- 5. 金錢
- 參與的類型
- 長期雇傭
- 作為一些個體出現,而不是一個整體
- 公開你的動機
- 錢不能讓你可愛
- 契約
- 資助非編程活動
- 市場營銷
- 6. 交流
- 人如其文
- 避免常見的陷阱
- 刺兒頭
- 處理成長
- Bug跟蹤系統中無對話
- 公開性
- 7. 打包、發布和日常開發
- 版本號
- 發布分支
- 穩定發布版本
- 打包
- 測試和發布
- 維護多發布線
- 發布和日常開發
- 8. 管理志愿者
- 從志愿者中獲取最多
- 像分擔技術任務一樣分擔管理任務
- 轉化
- 提交者
- 榮譽
- 分叉
- 9. 許可證,版權和專利
- 術語
- 許可證的方面
- GPL和許可證兼容性
- 選擇一個許可證
- 版權分配和所有權
- 雙許可證模式
- 專利
- 深入資源
- A. 自由版本控制系統
- B. 自由Bug跟蹤系統
- C. 為什么我要關注車棚的顏色?
- D. 報告bug的樣例指導
- E. 版權