測試 | 讓每一粒塵埃有的放矢
對很多開發人員來講,測試人員是掃雪工,沒什么真本事。并且,在他們自己構建代碼時,也對測試不屑一顧。要么是抱著老子天資聰慧,用不著這些繁文縟節的官僚流程;要么是覺得寫測試并沒有什么“實際”的貢獻,花了大量的功夫,似乎什么都沒有推進,什么實質性的feature都沒被實現,只不過是一堆檢驗性質的監視器罷了。
Linus對測試的看法就完全不一樣。在《關于git的主要維護者濱野純的訪談》一文中,有這樣一段論述:
Linus對每個貢獻者都很看重。我那時候也是,Linus對我說,雖然你的提交沒有被采用,但測試用例還是能用的,針對現在的實現,你稍微修正一下吧。
可見,在Linus的眼中,testcase是被認為是大于或等同于功能性開發的重要東西。因為,即便是你開發的功能性代碼沒有被使用,而接受你的測試集本身,也可以用來作為鼓勵你的重要東西。
在我看來,很多人對測試的理解不太透徹,也缺乏深度。其原因不是這個人的技術有問題,而是這個人所體現出來的個人習慣,或者工程素養有問題。
讓我們舉一個最簡單的例子,如果你發現你的電腦反應遲鈍,想要重裝系統,你會怎么做?
如果電腦里的文件比較少,估計很可能就直接重裝。而如果文件稍微大一點,或許會拷貝幾個重要目錄。而如果文件太過復雜,大部分人會在經歷了半小時的仔細核對后,毅然放棄,直接擼起袖子就開始重裝,并會在心里罵上幾句:神馬破玩意兒,浪費我這么多時間!管那么多干嘛,舊的不去新的不來!
而什么是良好的工程素養呢?就是首先,在發生重裝系統這個事情之間,他就會好好規劃自己的文件安放問題,并作出一些預案。再來,如果真的是拿到一堆爛攤子,他也不會這么魯莽。擁有良好工程素養的人,一定會按部就班地將所有文件仔細核對后,做出相應的備份,再記錄好相關的引用關系。甚至還會優先考慮失敗預案,最后才是做重裝系統這一步。
重裝系統就像是爆破一棟樓房。拙劣的工程師,只會不管三七二十一,直接行使最暢快的“爆破”動作。而好一點的工程師,會留出足夠的預案和備選,至少要做到先把爆破附近的無關人員疏散走吧。而卓越的工程師,則會精密地去制定自己的方案,力求做到讓每一粒塵埃都有的放矢,讓每一塊磚石在掉落地面的時候,都能夠被救生毯準確接住。
那這與開發、測試有什么關系呢?其實,開發就是爆破的炸彈,直接行使最搶眼球但卻是最簡單粗暴的部分。而測試是默默無聞的,是預案、是隱線、是為每一塊飛落出去的磚石墊底的毯子!
表面上,這堆毯子并沒有什么用,因為你的任務是爆破,不是生產毯子。可是,一場不顧影響、不顧周圍人員死活的爆破,到底是破壞性的戰爭行為還是建設性的工程行為?這就完全取決于你是否為這場爆破做了規劃、做好了預案。
測試,是開發的防彈衣、兜底布,讓你的開發爆破行為不再血水四濺、尸橫遍野。它是你自己的保護傘、是周圍人員的防護罩,讓你的開發行為從暴力性質變為建設性質。
而另一方面,編寫測試集,并沒有想象中的那么缺乏技術性。某種意義上來講,測試集(特別是Regression測試集)的編寫,其實就是“技術壁壘”的真正所指。Regression測試的建立過程,其實就是一個團隊成長過程的積累。每當遇到一個大坑,它的fix和修復后的testcase,就會被吸收進Regression測試集,永遠地服務于未來的開發。
試想,如果你的這些fix,都無法以Regression測試集的方式被吸收,那請問這些曾經淌過的渾水和經歷過的傷痛豈不都白費了?它無法被不斷復用,也無法被用來服務未來的開發,其價值,豈不是就這樣損失了?
這些通過實踐和歷史累積下來的東西,才是真正的“技術壁壘”!它不可能是哪個天資聰穎的開發人員的靈機一動或者突發奇想就能做出來的。它是確確實實的、在每一個歷史節點上的、在每一段嘔心瀝血的戰斗后,保存下來永遠服務于未來的歷史資產!這種靠歲月累積下來的東西,牢固而強大,不是一朝一夕、或者某份天資聰穎就能取代的。這才是一個組織的技術沉淀,是真正不可撼動的寶貴資產。
而這份資產是什么呢?就是最開始談到的,被大部分開發人員所忽視的測試。