讓我們一起聊聊單元測試的恩怨
單元測試是一個偉大的發(fā)明,同時也是一個操蛋的發(fā)明。只要團隊碰它,幾乎很難全身而退。
如果是我們自己寫的代碼,那么,寫寫單元測試也無傷大雅。但我們絕大多數(shù)人,都是跟在別人后面打掃狗屎,或者是留給別人一堆狗屎。這時候,單元測試寫起來,就有一種不情不愿的味道。
沒錯,就是不想寫!
為了應付所謂的指標,我們要給那些遺留代碼,將要發(fā)臭的代碼上一劑良藥:那就是自動化。假如這些糟心的代碼,大部分交給機器去寫,我想很多人是非常樂意的。
squaretest
有很多這樣的工具,比如IDEA自帶的。但是它只能生成一些表面功夫的東西,也就是生成一個骨架而已。
說實話,并沒有什么鳥用。根本就沒減少我多少的工作量,該覆蓋不到的代碼,還是覆蓋不到。
這個時候,我們需要更高級一點的工具。經過測試,現(xiàn)在瞄準了squaretest。
在IDEA的插件安裝界面中,找到squaretest并安裝之,你就會擁有這個功能。
重啟IDEA之后,從你的屎山中,找到最臭的那一塊,然后就可以在菜單中找到這個工具,生成代碼。
中間的話,可能會讓你選擇一下語言,選擇一下模版之類的,這對于一個搞軟件的來說并不是難事,所以這里也不再啰嗦。
好家伙,足足給我生成了上萬行的test代碼。這時候,無論是交給QA看,還是交給分析工具去玩,都能閃瞎它們的狗眼。
hehehehehehe....漂亮!
報錯不少,還得微調一下參數(shù)。但大多數(shù)代碼已經生成好了,已經節(jié)約了很大的力氣了。
其他工具
這貌似不是一個好的賽道。因為很多工具都不怎么維護了,或者不怎么好用。用愛發(fā)電越來越行不通了。
比如JUnitGenerator2.0,連JUnit5都不支持;AgitarOne,雖然只有30天的試用期,但主頁也和上古怪獸一樣;Randoop的使用,根本就不是為人類設計的;Analytix被google收購后,幾乎進入了墳墓。
squaretest,可以說是非常好用了。
你需要單元測試么?
很多人沒得選,因為這是硬指標。如果你的工作流程有問題,單元測試不但不能增彩,反而會成為累贅。
大多數(shù)情況下,單元測試不會減少bug,它們會根據bug進行調整,以適應正常代碼;另外,如果你的代碼都是一些簡單的CRUD,寫單元測試看不到任何有益的地方。
這個現(xiàn)狀,還是要從根源上找原因。
中國式需求,變化奇快,臨時需求多,要求快速交付。這些功能,往往復雜性比較低,編寫的代碼并不會產生過多的bug;由于變化快,編寫的單元測試也沒有通用的可能性;一次性的代碼,寫完之后可能永遠不再修改,被扔在一個遺忘的角落。
要寫單元測試,你要確保你的單元測試多年之后還可以用。而不是等到項目尾聲,為了達到指標而集中補充單元測試。單元測試要想發(fā)揮它的價值,需要在一開始就創(chuàng)建相關的代碼,捫心自問,很多團隊是做不到這一點的。
做不到,就不要裝。
單元測試并不簡單
有意思的是,即使環(huán)境達到了要求,所有的接口都提前設計了,且保持較少的變動,我們依然無法推行單元測試。
單元測試從來不是因為寫單元測試有多困難,而是大多數(shù)代碼,是無法寫出好的單元測試的。
在TDD(Test-Driven Development,測試驅動開發(fā))模式下,測試的動作比開發(fā)早,屬于預先設計接口定義的范疇。如果你在后期對接口進行了較多的變更,這種方式同樣會讓開發(fā)人員變的痛苦不堪。
單元測試需要配合極限編程,經常對代碼進行重構。這是設計腐化之后的一種補救式措施。但很多情況下,大家都害怕、拒絕對舊代碼進行修改。工期和穩(wěn)定性是常見的借口,這些借口看起來比擴展性和可測試性看起來更正常一些,也更能說服高層進行決策。
沒有幾個技術決策者,能夠在銷售、產品、老板的重重壓力下保持初心,做這種長遠性的規(guī)劃。所以說單元測試肯定是有用的,但卻缺乏實施的土壤。按時上線、提前上線、bug數(shù)量,這些常見的指標,只反映了結果,那些去改進這些結果的措施,短期效應不是很明顯的話,很容易就胎死腹中。
單元測試還阻礙開發(fā)人員重構的動力。因為重構意味著要動很多的測試代碼,往往很多人偷偷一評估,就放棄了。
堅持對的事情
選擇一個優(yōu)秀的團隊,是非常重要的。大家都很專業(yè),不會虧待你所信仰的正確。專業(yè)的人才在二流子團隊中,會像一個小丑一樣無助,大多數(shù)習以為常的經驗,幾乎無法實施。
讓人欣慰的是,追求原則的團隊還是有的,正確的方式可以避免很多曲折的路線,拋掉技術債所造成的負面影響。能夠加入這些團隊,是非常幸福的事情。
作為程序員,應該時刻保持這種好的習慣,不要因為趕工,忽略了代碼的重構和測試。這些是一個專業(yè)的技術人員應有的素質,而不是寄希望于公司的大環(huán)境中。這些好的習慣,就像人的氣質一樣讓人著迷,最終會讓你超脫于其他人而受益。
作為技術管理者,你要正確評估自己的公司環(huán)境,是不是具有單元測試的生長土壤。即使你明白單元測試是有益的,你也不得不做一些取舍。尤其是你判斷項目只不過是你的墊腳石,3年之后肯定不會在自己的手里,你更會任由它自我腐爛掉。如此情況,大家都心知肚明,沒人會對你說三道四。
作為非技術管理人員,當有人為你提出類似這種耗費工期的,長遠有益的建議,不要著急否定??匆豢雌渌麅?yōu)秀的企業(yè),是不是也曾因這些短暫的原地踏步而受益過。無知并不可怕,可怕的是不相信專業(yè)。如果你肯定了,給予支持,而不要半途而廢。有意思的是,半途而廢最終并不會廢止,它同樣會蛻變?yōu)樾问街髁x,將一件美好的事情硬生生變成指標。
End
單元測試代碼是無聊的、枯燥的,尤其是為別人寫的代碼補充單元測試。通常情況下,如果不發(fā)生bug,沒有人會閑的蛋疼去動那一堆堆的屎山,除非是不自量力的小牛犢。
這個時候,一個得心應手的工具,自動幫你完成這些操蛋的工作,讓你的單元測試代碼擁有和屎山一樣的生命周期,不得不說是一件快事。
作者簡介:小姐姐味道 (xjjdog),一個不允許程序員走彎路的公眾號。聚焦基礎架構和Linux。十年架構,日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。我的個人微信xjjdog0,歡迎添加好友,進一步交流。