11 個高效的同行程式碼審查最佳實踐

發表於2012-08-09

來源:IBM Developworks

簡介: 這 11 項針對輕量級高效同行程式碼評審最佳實踐被證明是有效的,它們建立在一個通過結合使用 IBM® Rational Team Concert™ 與 SmartBear CodeCollaborator 對 Cisco 系統的開發進行案例研究的基礎之上。它們可以幫助您確保評審既能夠改進您的程式碼,又能利用好開發人員的時間。

SmartBear Software 團隊® 花費了數年時間去搜尋已有的程式碼評審研究成果,並從來自超過 100 家公司的 6000 多名程式設計師那裡,收集了“實踐經驗”。很顯然,人們在評審程式碼時會發現一些錯誤(bug),但是這種評審工作通常會花費大量的時間,因此變得不太實際。我們通過數十年的經驗使用獲得的資訊,來建立輕量級程式碼評審的概念。通過使用輕量級程式碼評審技術,開發員只需要花費五分之一的時間就可以進行全面且規範的程式碼評審工作了。我們還開發了最佳實踐的理論,以便部署實現評審的效率與價值。本文概括了以下的這些實踐。

為了測試我們對程式碼評審及輕量級評審的結論,我們對程式碼評審進行了最大規模的研究工作。它涉及包含了2500 個程式碼評審案例,50 個程式設計師,及 Cisco 系統上320 萬行的程式碼。在 10 個月的時間內,研究追蹤了 MeetingPlace 產品團隊,該團隊擁有 Bangalore,Budapest 及 San José 方面的成員。

在研究開始時,我們要為這個團隊建立以下的規則:

  • 在檢入到團隊的版本控制軟體之前,所有的程式碼都必須進行評審。
  • SmartBear 的 CodeCollaborator® 程式碼評審軟體工具,應該用於精化,組織和改進所有的程式碼評審工作。
  • 程式碼評審的全體會議是不支援的。
  • 評審過程會得到工具的支援。
  • CodeCollaborator 會自動收集工具,提供評審層次和總結層次的報告。

根據我們的研究結果,總結了 11 項最佳實踐

您應該警惕,平等程式碼評審(在該過程中,軟體釋出以確保質量之前,軟體開發員會相互評審程式碼)會識別程式碼中存在的錯誤(bug),鼓勵協作,並使程式碼變得更有維護性。

但是很明顯的一點是,有些程式碼評審技術是低效低能的。評審過程中的一些會議會佔用時間,並抑制活力。嚴格的流程會扼殺創造力,但是鬆散的流程又意味著沒人知道評審是否有效,甚至是否發生。而個人批評的社會效應,又會損傷士氣。

本文描述了考慮效率時的 11 項最佳實踐,科學研究和 SmartBear 領域內的經驗證明輕量級同行評審是高效的。使用這些技術,可以確保程式碼評審能夠改進程式碼 – 而不用佔用開發員的時間。您可以使用最近的技術,來在 IBM® Rational Team Concert® 環境之中評審程式碼。

1. 一次評審量要低於 200–400 行程式碼

Cisco 程式碼評審研究(見於工具欄)顯示了為了得到優化的效率,開發員的評審量要低於一次 200-400 行程式碼(LOC)。超過這個量,搜尋缺陷的能力就會降低。以這個速度,您可以找到 70-90% 的缺陷。換句話說,如果存在 10 個缺陷,那麼您可以找到其中的 7 到 9 個。

關於 Cisco 案例研究

在 10 個月的監視工作之後,研究總結出了一個理論:如果適當操作的話,輕量級程式碼評審工作與規範的評審工作同樣有效,但是前者的速度會更快(更省時)。與規範評審相比,輕量級程式碼評審平均要少花 6.5 個小時,並發現更多的錯誤(bug)。

除了確認這些理論,研究中還發現了一些新的規律,本文將這些規律都概括了出來。

圖 1 中的圖,描述了缺陷密度與評審程式碼行數量之間的關係,支援該規則。缺陷密度 就是每 1000 行程式碼之中所發現的錯誤(bug)數。評審程式碼行的數量超過 200 時,缺陷密度就會急劇地下降。

在這種情況下,缺陷密度就是“評審有效性”的評價手段。如果兩個評審員評審相同的程式碼,其中一個發現了更多的錯誤(bug),那麼我們就會認為該評審員更有效率。圖 1 顯示了當我們將更多的程式碼放到評審者面前時,她搜尋缺陷效率的變化情況。這種結果很合理,因為她可能不會花費大量的時間去評審,這樣就會不可避免的使得效率沒有以前高。

圖 1. 當程式碼行數量超過 200 時缺陷密度就會急劇下降,400 以後缺陷密度幾乎為 0

11 個高效的同行程式碼審查最佳實踐
2. 每小時低於 300–500 LOC 檢查率的目標

定義

●檢查率: 我們能夠多快地評審程式碼呢?通常以每小時 kLOC(千程式碼行)來評價。

●缺陷率: 我們能夠多快地發現缺陷呢?通常以每小時缺陷數來評價。

●缺陷密度: 給定量的程式碼之中我們能夠發現多少的缺陷呢(而不是它們有多少)?通常以每 kLOC 中發現的缺陷數來評價。

您要花點時間進行程式碼評審。快速評審並不總是好的。我們的研究結果顯示檢查率低於“300-500 LOC/小時”時,可以得到優化的結果。根據所作的決定,評審者的檢查率有很大的變化,就算是相似的程式碼開發者、評審者,檔案和評審規模,也存在巨大的差異。

為了找到優化的檢查率,我們將 缺陷密度 與評審者檢查程式碼的 速度 進行了比較。得到的結果再一次落在了我們的預料之中:如果在評審您不花足夠的時間,那麼您就不會發現太多的缺陷。如果評審者面臨大量程式碼的壓力,那麼他就不會每一行程式碼投入相同的注意力。他不能研究同一位置處更改的所有版本。

所以,多快算是太快呢?圖 2 顯示了答案:伺服器端每小時超過 400 LOC 的評審速度會降低效率。而每小時 1000 LOC 的速度,您可能已經推出了,以這樣的速度評審員可能根本都沒有細看程式碼。

圖 2. 評審量超過 500 行程式碼時檢查效率就會下降了

11 個高效的同行程式碼審查最佳實踐
3. 花足夠的時間進行適當緩慢的評審,但是不要超過 60-90 分鐘

永遠不要對一個原型程式碼評審超過 60-90 分鐘

我們應該討論,為了得到更好的結果,不應該過快地評價。但是您也不應該在一個位置花太多的時間。大約 60 分鐘後,評審者就會感到疲勞,於是就不會找到額外的缺陷了。這個結論得到了許多其他研究的支援。實際上,根據我們的常識,當人們從事注意力高度集中的活動時,效能狀態在 60-90 分鐘之後就會降低了。考慮到人體方面的限制,評審者在效能降低之前,不能評審超過 300–600 行的程式碼。

但反過來說,評審程式碼所花的時間不得低於五分鐘,就算程式碼只有一行也是如此。通常來說,單行的程式碼也會影響到整個的系統,所以花上五分鐘時間去檢查更改可能造成的結果是值得的。

4. 確定在評審開始之前程式碼開發者已經註釋原始碼了

在評審開始之前程式碼開發者可能就消除大多數的缺陷,這一點我們將會看到。如果我們需要開發員雙倍地檢查他們的工作,那麼評審可能更快地完成,而不用再去折中考慮程式碼質量的問題。就我們所知,這種特定的想法尚未得到研究,所以我們在 Cisco 研究期間對其進行了測試。

圖 3. 程式碼開發者準備對缺陷密度的震撼性效果

11 個高效的同行程式碼審查最佳實踐

程式碼開發者準備 說的是程式碼開發者在評審之前要先註釋他們的原始碼。我們發明了這個術語,以描述研究中所評價的特定行為模式,大約 15% 的評審會阻止程式碼開發者這樣做。註釋會指導評審者進行變更,顯示首先必須要檢視的檔案,並找到每一次程式碼更改的原因。這些註釋不是程式碼之中的評論,而只是給其他評審者看的評論。

我們的理論就是,因為程式碼開發者需要重新考慮,並解釋註釋過程中所發生的更改,所以程式碼開發者需要在評審開始之前就找出許多缺陷,以讓評審變得更加有效。如此,評審過程將會產生低密度的缺陷,因為更少的錯誤(bug)剩餘了。很明顯,與沒有程式碼開發者準備的評審相比,程式碼開發者準備之後的評審有更少的缺陷存在。

我們還考慮過一個悲觀的理論,以解釋錯誤(bug)的低發現率。是不是當程式碼開發者在作出一項評論時,評審者會有偏見,或者自鳴得意,這樣就不能儘可能多地發現錯誤(bug)了呢?我們隨機抽查了 300 個評審者進行研究,結果證實評審者在評審程式碼時確實非常小心,更少的錯誤(bug)被發現了。

5. 為程式碼評審建立可定量化的目標,並獲取制度,這樣您就可以改進流程了

有了專案,您就該決定程式碼評審過程的目標,以及怎樣評價效率問題了。當您在定義特定的目標時,您就能夠決定同行評審是否真的達到了您所需要的結果。

最好從外部性的制度開始,例如“將支援訪問降低 20%”或者“使開發引入的缺陷百分比減半”。這些資訊使您能夠更好地看清,從外部視角來看,程式碼能夠做些什麼,您還需要一個可定量化的評價手段,而不是“修復更多錯誤(bug)”的模糊目標。

但是,在外部制度顯示結果之前需要花上一段時間。例如,支援性訪問將不會得到影響,直到新的版本得到釋出並交到客戶手中為止。所以檢視內部性流程工具,以得到發現多少缺陷,缺陷就是問題所在,以及開發員在評審上所花時間的清晰結果。程式碼評審的最常見內部性制度是 檢查率 ,缺陷率,以及 缺陷密度。

考慮一下只有自動化或者緊密控制的流程,才能給您帶來可重複的程式碼;人類並不擅長記住啟動或者終止計時器。為了得到最好的結果,您要使用能夠 自動 收集程式碼的程式碼評審工具,這樣用於流程改進的關鍵程式碼就是精確的了。

為了改進和提高您的流程,您可以收集程式碼並組合流程,以檢視更改是如何影響結果的。很快,您就將會知道什麼工作最適合您的團隊了。

6. 使用檢查表,因為它能極大地影響程式碼開發者和評審者的結果

使用檢測表對於評審員非常重要,如果程式碼開發者忘記了某項任務,評審員也同樣可能忘記。

我們極力推薦您使用檢查表,來確定您可能會忘記的事情,它對程式碼開發者和評審者都有用。忽略是最難發現的缺陷;畢竟,評審不在那裡的東西是很困難的一件事。檢查表是解決這個問題的最好方式,因為它會提醒評審者和程式碼開發者花點時間去考慮一下可能被遺忘的事情。檢查表還會提醒程式碼開發者和評審者確定所有的錯誤(bug)都得到了處理,軟體功能已經通過了無效值測驗,而且已經建立了單元測試。

另外一個有用的概念就是 個人檢查表 。每個人一般都會犯 15-20 個錯誤(bug)。如果您注意到了一些典型的錯誤(bug),那麼您就可以開發自己的個人檢查表(Personal Software Process,Software Engineering Institute,以及 Capability Maturity Model Integrated 也都推薦該實踐方式)。評審者將會完成決定一般性錯誤(bug)的工作。您所應該做的,就是擁有一個簡短的檢查列表,一般都是您容易遺忘的事情。

一旦您開始在檢查列表中記錄自己的缺陷,那麼您就會少犯錯了。規則將不斷出現在您的腦海中,然後您的錯誤(bug)率就會下降了。這種情況我們將會發現它反覆出現。
提示:
如果您想要得到關於檢查列表的更多具體資訊,那麼您可以得到本文程式碼開發者所寫書籍的免費拷貝,這本書為 Best Kept Secrets of Peer Code Review,網址為 www.CodeReviewBook.com。

7. 確認缺陷得到了修復

是的,這種“最佳實踐”看起來好像是沒有腦子的。如果您遇到了評審程式碼以找到缺陷的所有問題,那麼修復它們就變得順理成章了!現在許多評審程式碼的團隊沒有一種好的辦法,去追蹤評審期間找到的缺陷,並確保評審完成之前錯誤(bug)確實得到了修復。確認電子郵件之中的結果,或者實時評審是非常困難的。

記住這些錯誤(bug)通常不是在 Rational Team Concert 日誌中輸入的,因為在程式碼釋出給 QA 之前就發現了這些錯誤(bug)。所以,什麼是程式碼在貼上“全部解決”標誌之前確認缺陷的好辦法呢?我們建議使用好的協作性評審軟體,與 Rational Team Concert 相整合,以追蹤評審之中所發現的缺陷。有了正確的工具,評審員就可以記錄錯誤(bug),並在必要時與程式碼開發者進行討論了。然後程式碼開發者會修復問題,並通知評審者,而評審者必須確認每個問題都得到了解決。工具應該追蹤評審期間所發現的問題,並確保直到所有的錯誤(bug)被評審者 修復 才完成評審(或者作為稍後解決的單獨工作項追蹤)。工作項只有在評審完成時才能通過。

如果您真面臨著搜尋錯誤(bug)的煩惱,那麼請確認您已經將它們全部安裝了!

既然您已經學會了程式碼評審 流程 的最佳實踐方式,那麼我們接下來將會討論一些社會效應,以及怎樣管理它們以獲得最佳的結果。

8. 培養良好的程式碼評審文化氛圍,在這樣的氛圍中可以積極地評審缺陷

與其他我們能看到的大多數技術相比,程式碼評審對於真實團隊構建能夠發揮更大的作用,但是隻是在管理人員能夠以一種積極的,向上的,有技巧的方式進行交流時,這種優勢才能發揮出來。將缺陷看做是不好的事物很容易(畢竟,它們是程式碼之中的錯誤(bug)),但是形成不好的缺陷檢查態度,則會毀掉整個團隊的努力,更不要說它會破壞錯誤(bug)檢查過程了。

軟體程式碼評審的要點在於,儘可能多的消除缺陷,不管是誰“導致”了錯誤(bug)。

管理人員必須建立缺陷是積極的這樣的觀點。畢竟,每一個缺陷的存在,都是改進程式碼的潛在機會,而錯誤(bug)評審過程的目的,就在於使程式碼儘可能地完美。每一個被發現並解決的缺陷,都是客戶以後不會看到的缺陷,也是 QA 人員不必花費時間去解決的問題。

團隊需要維持這樣一種態度,就是發現缺陷,就意味著程式碼開發者和評審者 作為一個團隊 去改進產品的質量成功了。而不是“程式碼開發者產生了一個缺陷,而評審者負責去發現它”。它更像是配對程式設計的一種有效形式。

評審員要向所有的開發者展示收集壞習慣,學習新技巧,並展開功能的機會。開發員可以從他們的錯誤(bug)中學習,但是隻是在他們警惕錯誤(bug)時才會這樣。如果開發員害怕發現錯誤(bug),那麼積極的結果就會消失。

如果您是一名初級開發員,或者是一個團隊的新成員,那麼其他人發現缺陷時,就意味著您強有力的隊友在幫助您成長為一個合格的開發員。這就比您單槍匹馬地程式設計,沒有具體的反饋時,要更快地進步。

為了維持檢查缺陷是積極的這樣一種理念,管理人員必須要承諾缺陷密度不會進入到效能報告之中。公開作出這種承諾是很有效的。這樣開發員就會知道他們要怎樣做,並抗議公開破壞這條規則的管理人員。

管理人員絕不應該將錯誤(bug)程式碼作為消極效能評審的基礎。他們必須謹慎對待,並對批評造成的挫折感及消極反應保持敏感,並要一直提醒團隊發現錯誤(bug)是一件很好的事情。

9. 警惕老大哥效應(Big Brother Effect)

作為一個開發員,您可以自動假設“老大哥正看著您呢”是真的,如果評審制度是由評審支援工具自動評價的,更是這樣的。您是否花費了很長的時間去評審一下更改?您的同行從您的程式碼中是否發現了很多錯誤(bug)?這將如何影響您下一步的效能評價?

評估報表不應用來對付開發人員,尤其是在面對結對評審員時。這一做法會嚴重破壞道德觀。

制度對於流程評價來說非常重要,這反過來,又為流程改進提供了一個基礎。但是制度也可以被用來做壞事。如果開發員相信制度是用來對付他們的,那麼他們不光是對流程有敵意,而且他們的注意力可能轉到改變制度,而不是編寫更好的程式碼,和變得更有效率上。

管理員可以做很多事情,來解決這個問題。首先也是最重要的,他們必須要警惕這一點,並且必須確定程式碼開發者沒有面臨很多的壓力,而“老大哥”問題必須每次都得到詳細的檢查。

制度應該用來評價流程的效率,或者流程更改的效果。記住,通常來說,最困難的程式碼是由最有經驗的開發員處理的。這些程式碼,反過來,最有可能出問題,因此最難檢查,也有可能發現最多的缺陷。因此,大量的缺陷很有可能是由複雜性,以及程式碼的分塊性造成的,而不是程式碼開發者的能力造成的。

如果制度確實能夠幫助一個管理員去發現一個問題,那麼將某人踢出局可能會產生更多的問題。我們推薦管理員在解決相關問題時,要將一個小組當做整體來對待。所以最好不要召開專門的會議,因為開發員在解決特定的問題可能會有壓力。相反,您可以通過一個每週狀態會議,或者正常的程式來解決問題。

管理員必須不斷地維持這樣一個年頭,即搜尋缺陷是好的事情,而不是糟糕的,缺陷密度與開發員的能力並不是掛鉤的。記住對一個團隊來說,缺陷,尤其是團隊成員所引入缺陷的數量不應該被迴避,也不應該用作能力的評價引數。

10. 評審一部分的程式碼,就算您不能全部完成,以從自我效能感(Ego Effect)中獲益

想象一下您自己坐在編譯器的前面,任務是需要修復一個小小的錯誤(bug)。但是您知道只要您說出了“我完成了”,您的同行 — 或者更糟,您的老闆 — 就要檢查您的工作了。這會改變您的開發個性嗎?所以在您工作時,一般是在您宣告程式碼評審完成之前,就會更加的謹慎了。如此您立即就會成為一個更好的開發員了,因為在您背後別人議論您時就會說,“他的員工非常謹慎,他真是一個不錯的開發員”;而不是“他犯了大量愚蠢的錯誤(bug)。當他說工作完成時,實際上還差著遠呢”。

自我效能感(Ego Effect)會促使開發員編寫更好的程式碼,因為他們知道其他人將會檢視自己編寫的程式碼及作品。沒有人想被其他人認為自己經常犯初級的錯誤(bug)。Ego Effect 促使開發員在向其他人交付作品時更加謹慎地進行評審。

Ego Effect 的一個良好特徵,是不管評審者要對所有的程式碼變更負責,還是僅僅執行“點檢查”,就像隨機性的藥物測試一樣,都能正常地發揮作用。如果您的程式碼有三分之一的機率被評審者抽中進行評審,那麼它仍然足以刺激評審者謹慎工作。如果您只有十分之一的概率被抽中檢查,那麼可能您就不會如此勤奮了。您知道您會說,“哈,我很少犯錯”。

評審 20–33% 的程式碼時,從 Ego Effect 中獲得花費時間方面的收益可能最大,評審 20% 的程式碼肯定要比不評審強很多。

11. 採用輕量級,工具支援的程式碼評審

程式碼評審一般有些主要的型別和無數的變數,而指南卻能適用它們中的任何一個。但是,為了完全優化團隊花在評審之上的時間,我們要使用工具支援的輕量級評審過程來得到最優的結果。搜尋缺席時,它是有效的,實用的。

規範,或者 重量級的 檢查已經流行了 30 年。它已經不是評審程式碼的有效形式了。重量級檢查平均花費的時間是每 200 行程式碼 9 個小時。儘管它很有效,但是嚴格的過程需要三到六個參與者,並進行一系列繁瑣的會議以討論具體的細節。不幸的是,儘管需要繁瑣的過程,但是大多數的公司沒有條件將程式設計人員整合起來,進行長時間的會議。最近的幾年,許多開發公司已經完全放棄了會議安排,紙質程式碼閱讀,以及繁瑣的作品收集工作,轉而採用新型 輕量級 過程,以從規範的會議及老式重量級過程的重壓中解放起來。

我們使用在 Cisco 中的案例研究,來確定輕量級技術與規範過程比較的特點。結果顯示輕量級程式碼評審所需要的時間只是規範評審的五分之一(甚至更少),而且前者能夠發現更多的錯誤(bug)。

儘管輕量級程式碼評審擁有很多的方法,例如實時評審和電子郵件評審,但是最有效的評審方法還是使用協作性的軟體工具來促進評審,這些軟體工具例如 SmartBear 的 CodeCollaborator(見於圖 4)。

圖 4. Cisco 研究中所使用到的輕量級程式碼評審工具,CodeCollaborator

11 個高效的同行程式碼審查最佳實踐

CodeCollaborator 是與 IBM® Rational Team Concert 工作流程相整合的唯一程式碼評審工具。它將原始碼評審與聊天形式的協作整合起來,從而使開發員從聯絡註釋與私人程式碼行的繁瑣活動中解放了出來。當程式設計師向工作項新增更改項進行評審時,在 CodeCollaborator 中將會自動建立評審,並分配適當的批准者。團隊成員可以直接註釋程式碼,與程式碼開發者聊天,並就每一個問題進行協作,追蹤錯誤(bug)並修復缺陷。整個過程不需要會議,列印,或者安排日程。

有了基於 Rational Team Concert 與 CodeCollaborator 的輕量級評審過程,團隊就可以進行更有效的評審,並實現程式碼評審的有利點。

CodeCollaborator 獲得了 “Ready for IBM Rational Software” 針對 Rational Team Concert V2 和 V3 的認證,以及針對 IBM® Rational® ClearCase® 和 IBM® Rational® Synergy® 的認證。

到現在為止,您已經被經實踐證明有效的經驗從頭到尾武裝起來了,以確保從過程和社會的角度來看,團隊在程式碼評審過程之中能夠節省大量的時間。當然,您必須確實 完成了 程式碼評審,以實現這些便利。對 100% 的程式碼使用評審的規範方法(有人對這個百分比存在異議,簡單來說是不現實的。整合到 Rational Team Concert 環境之中的工具支援輕量級程式碼評審,提供了最強大的功能,因為它提供了一個有效的方法去搜尋缺陷,而且不會涉及到開發員頭痛的一些問題。有了正確的工具和這些實踐方式,您的團隊就可以對所有的程式碼進行同行評審,並在軟體達到 QA 階段之前就找到成本極高的錯誤(bug),這樣您的客戶每次都能夠得到頂級品質的產品了。

為了方便您檢視,下面總結了在一個簡單列表中最容易保持的 11 項實踐方式:

1、一次評審少於 200–400 行的程式碼。

2、目標為每小時低於 300–500 LOC 的檢查速率。

3、花足夠的時間進行正確緩慢的評審,但是不要超過 60–90 分鐘。

4、確定程式碼開發者在評審開始之前就已經註釋了原始碼。

5、為程式碼評審和獲取制度建立可定量化的目標,這樣您才能改進流程。

6、使用檢查列表,因為它可以極大地改進程式碼開發者和評審者的作品。

7、確認缺陷確實得到修復了。

8、培養良好的程式碼評審文化氛圍,在這樣的氛圍中搜尋缺陷被看做是積極的活動。

9、警惕“老大”效應。

10、最少評審一部分程式碼,就是您不能評審全部的程式碼,以從 Ego Effect 中受益。

11、採用輕量級,能用工具支援的程式碼評審。

相關文章