事后敲打()是常見的工作方式,行業(yè)占統(tǒng)治地位的瀑布開發(fā)方法就是這樣:規(guī)格說明、設(shè)計(jì)、構(gòu)建、測試。測試是最后的步驟。產(chǎn)品來到測試部門,很快就崩潰了。于是,又回到工程部門,修復(fù)Bug。接著,把另一版提交給測試部門,又由于其他原因崩潰。就這樣,來來回回,許多月(甚至是數(shù)年)流逝。
在程序員們深入具體實(shí)踐之前,我們會從技巧1——敲打代碼開始,幫你建立正確的思維方式。
你可能認(rèn)為編寫可靠代碼是再明顯不過的工作要求了。招工廣告上不可能寫:“急聘:具備良好工作態(tài)度、團(tuán)隊(duì)合作精神和桌上足球技巧的程序員。有則更佳:會編寫可靠的代碼?!笨捎袉栴}的程序還是有這么多,怎么回事?
在深入探討保證代碼質(zhì)量的日常實(shí)踐之前,讓我們先討論“編寫可靠代碼”的含義。它不僅僅是一份實(shí)踐清單,它還是一種思維方式。在把產(chǎn)品交到客戶手中之前,你必須敲打自己的代碼和整個產(chǎn)品。
客戶終究敲打你的產(chǎn)品,以一種你不曾預(yù)料到的方式使用它。他們用它的時間會很長,而且會在你沒有測試過的環(huán)境里用它。你必須考慮的問題是:打算讓客戶發(fā)現(xiàn)多少Bug?
你現(xiàn)在對代碼敲打的次數(shù)越多,在交到客戶手中之前,能清除掉的Bug就越多,留給客戶的Bug就越少。
質(zhì)量保證的形式
1.代碼評審
保證代碼質(zhì)量最簡單的方法就是讓另一個程序員去讀它。別出心裁的評審過程并沒有必要,而且就連結(jié)對編程也算是一種形式的實(shí)時代碼評審。團(tuán)隊(duì)將利用代碼評審捕獲Bug,貫徹編程風(fēng)格和標(biāo)準(zhǔn),同時在團(tuán)隊(duì)成員間傳播知識。我們將在“技巧8:代碼評審要早且多”中討論代碼評審。
2.單元測試
在你一個類接著一個類、一個方法接著一個方法地構(gòu)建應(yīng)用的業(yè)務(wù)邏輯時,驗(yàn)證代碼的最佳方式就是單元測試。這種內(nèi)部零件級的測試被設(shè)計(jì)用來對邏輯的各部分單獨(dú)驗(yàn)證。
3.接受測試
單元測試立足于由內(nèi)而外地審視產(chǎn)品,接受測試則被設(shè)計(jì)成模擬真實(shí)世界的用戶,代表他們與系統(tǒng)交互。理想狀況下,它們是自動執(zhí)行的,而且以某種敘述式的風(fēng)格書寫出來。例如,某銀行自動柜員機(jī)應(yīng)用會有類似這樣的接受故事:若我的活期存款為0,當(dāng)我在ATM的“活期存款”中選擇“取款”時,那么我應(yīng)該看到“對不起,今天的晚餐吃泡面吧。”
它不像莎翁著作那樣文采飛揚(yáng),但這些測試操練了整個系統(tǒng):從用戶界面一直到業(yè)務(wù)邏輯。無論它們是自動執(zhí)行的,還是人工執(zhí)行的,你的公司需要知道—在任何客戶使用它之前—所有系統(tǒng)組件正在像預(yù)期的那樣協(xié)調(diào)工作。
4.負(fù)載測試
負(fù)載測試將產(chǎn)品置于真實(shí)的壓力條件下,然后度量它的響應(yīng)。例如,某網(wǎng)站可能需要在數(shù)據(jù)庫有100萬條記錄的條件下在100毫秒內(nèi)展示指定頁面。這些測試將揭示正確但不恰當(dāng)?shù)男袨?,如需要線性伸縮但卻以指數(shù)級別伸縮的代碼。
5.定向探索測試
接受測試覆蓋了產(chǎn)品的所有指定行為,它可能來自于產(chǎn)品需求文檔或會議。但程序員通常還是有辦法使之崩潰—總有些黑暗角落被規(guī)格說明疏忽掉。定向探索測試就是要將這些邊界情況挖出來。
這種測試通常是人工執(zhí)行的,可能是程序員自己,用于探索和發(fā)現(xiàn)問題。但最初探索之后,任何有用的測試就會被加到接受測試套件之中。
該測試有一個專業(yè)化的變種,如安全審計(jì)。在這些情況下,專業(yè)測試人員會利用他們的領(lǐng)域知識(可能也包括代碼評審)來指導(dǎo)他們的測試。
6.機(jī)構(gòu)測試
硬件產(chǎn)品需要不同的機(jī)構(gòu)認(rèn)證:FCC度量電磁輻射,確保產(chǎn)品不會導(dǎo)致無線電干擾;美國保險(xiǎn)商實(shí)驗(yàn)室(UL)檢查當(dāng)你將產(chǎn)品置于火上或舔電池電極時會發(fā)生什么。這些測試都在新產(chǎn)品發(fā)布之前進(jìn)行,每次硬件變化都會影響認(rèn)證。
7.環(huán)境測試
硬件產(chǎn)品的運(yùn)行溫度和濕度也需要在推至極限時測試。這些測試是用環(huán)境室來完成的,它可以同時控制這兩個因素;當(dāng)產(chǎn)品在其間運(yùn)行時,它會經(jīng)歷所有四種極限條件。
8.兼容性測試
一旦產(chǎn)品需要跟其他產(chǎn)品進(jìn)行互操作(如某字處理程序需要跟其他字處理程序交換文檔),這些兼容性的論斷就需要定期驗(yàn)證。它們可能會訪問一組已保存的文檔,也可能會實(shí)時地將你的產(chǎn)品連接到其他產(chǎn)品上。
9.耐久性測試
你會注意到這里提到的大多數(shù)測試都是盡量頻繁且快速地運(yùn)行??捎行〣ug只會在一段時間的使用之后現(xiàn)身。前面提到的49.7天的Bug很好說明了這一點(diǎn)—它源于每毫秒遞增的32位計(jì)數(shù)器,在49.7天之后,它會從最大值反轉(zhuǎn)成0。測試若不持續(xù)運(yùn)行上一會兒,你就無法發(fā)現(xiàn)類似Bug。
10.Beta測試
產(chǎn)品在這一階段被送到了真實(shí)客戶手中—他們知道自己要參加測試,并同意發(fā)現(xiàn)問題時提交報(bào)告。Beta測試的目的就在于我們在本技巧一開始討論的:Beta測試者將以你意想不到的方式使用產(chǎn)品,試用它一段時間,并在你沒有測試過的環(huán)境中測試產(chǎn)品。
11.運(yùn)行中測試
公司可能會在產(chǎn)品上市之后繼續(xù)測試。尤其是硬件產(chǎn)品,如偶爾從制造線上拔掉一個單元并證明制造線能工作正常是一種很有用的方法。這些運(yùn)行中測試的設(shè)計(jì)目的就是為了捕獲因零件或裝配過程中的變化而導(dǎo)致的問題。
實(shí)踐 VS 思維方式
你的團(tuán)隊(duì)可能采用類似“所有代碼都必須有單元測試”或“所有代碼必須先評審后檢入(check in)”的實(shí)踐。但這些實(shí)踐沒有一個能保證代碼堅(jiān)若磐石。想想若公司根本就沒有采用一個質(zhì)量實(shí)踐,這種狀況下該怎么做,即你將如何敲打代碼以保證它的可靠性?
這是在繼續(xù)深入之前你需要建立的思維方式。提交可靠的代碼。質(zhì)量實(shí)踐只是達(dá)到目的的一種手段—最終的裁判是客戶手中產(chǎn)品的可靠性。你想讓你的名字跟市面上滿是Bug的垃圾產(chǎn)品掛鉤嗎?不,當(dāng)然不想。
行動指南
在上述所有形式的測試中,你的公司采用了哪些?在源代碼中尋找單元測試,向測試部門詢問接受測試計(jì)劃,問問Beta測試是如何進(jìn)行的以及向哪個部門提交反饋。再問下資深工程師:這是否足以保證客戶有一個平滑的體驗(yàn)?
在定向探索測試上多花些時間,哪怕你的“方向”有點(diǎn)兒模糊。實(shí)際用一下產(chǎn)品,看看你是否可以讓它崩潰。如果可以,那就相應(yīng)地記下Bug報(bào)告。
作者Josh Carter,資深軟件設(shè)計(jì)師,具有超過20年編程行業(yè)從業(yè)經(jīng)驗(yàn)。熱衷于編程和追逐前沿技術(shù),但同時謹(jǐn)記史蒂夫?喬布斯的箴言“真正的藝術(shù)家能讓產(chǎn)品面市”。他還涉足工程管理領(lǐng)域,曾經(jīng)主管大型企業(yè)軟件開發(fā)團(tuán)隊(duì)。目前已出版多本關(guān)于計(jì)算機(jī)軟件的技術(shù)書籍,同時他還在主流計(jì)算機(jī)雜志的技術(shù)專欄發(fā)表文章。
本文節(jié)選自《程序員修煉之道:專業(yè)程序員必知的33個技巧》一書。Josh Carter著,胡鍵譯,由機(jī)械工業(yè)出版社出版。
聯(lián)系客服