qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問 http://qaseven.github.io/

          單元測試

          想當(dāng)年畢業(yè)設(shè)計(jì)就是測試驅(qū)動(dòng)開發(fā),所以從剛?cè)胄虚_始就對(duì)單元測試、測試驅(qū)動(dòng)開發(fā)有比較深入的認(rèn)識(shí),剛開始一直作為敏捷開發(fā)的忠實(shí)粉絲。但是幾年工作下來,我開始對(duì)單元測試持矛盾的態(tài)度:單元測試當(dāng)然是一種很好的創(chuàng)舉,但是具體使用當(dāng)中,它卻經(jīng)常會(huì)產(chǎn)生副作用。這當(dāng)然不是因?yàn)閱卧獪y試這一思想有問題,而是實(shí)踐這一思想的人的問題。

            當(dāng)前很多公司使用單元測試的怪現(xiàn)象:

            很多公司為了說出去好看——我們的開發(fā)遵循敏捷開發(fā),擁有近100%的單元測試覆蓋率,所以代碼質(zhì)量有非常可靠的保障。但是實(shí)際上,單元測試都是軟件已經(jīng)開發(fā)完成之后加上去的,而且經(jīng)常還是由專門分配的幾個(gè)人去寫單元測試的,而這幾個(gè)人根本不熟悉需求,甚至根本沒有參與開發(fā)過程,或者參與得很少,而分配給他們寫單元測試代碼的時(shí)間當(dāng)然也很緊張,因?yàn)檫@也是需要成本的。所以,最終導(dǎo)致的結(jié)果就是——為了達(dá)到覆蓋率目標(biāo),為每個(gè)方法(不管有無必要)加上單元測試,簡單看一下這個(gè)方法,然后從對(duì)這個(gè)方法的膚淺理解出發(fā),即開始動(dòng)手,寫一個(gè)或很少的幾個(gè)測試用例,這樣單元測試覆蓋率100%的要求就達(dá)到了,可是這樣的單元測試有用嗎?答案不言自明。

            這種怪現(xiàn)象一般可能具備哪些特征呢?

            1、整個(gè)開發(fā)過程完全之后寫單元測試——這是單元測試的時(shí)機(jī)問題

            2、由非開發(fā)過程的參與者寫單元測試——這是單元測試的執(zhí)行者的角色問題

            3、由不了解需求的人員寫單元測試——這也是單元測試的執(zhí)行者的角色問題

            那么,這種行為會(huì)帶來哪些副作用呢?

            1、這浪費(fèi)了時(shí)間和人力成本

            2、這會(huì)帶來負(fù)面的情緒影響

            這些人是帶著抵觸的厭煩的情緒投入工作的,因?yàn)槊髦@樣的工作是無用功,僅僅是面子工程,卻不得已而為之,自然沒有興趣沒有熱情,而這一情緒會(huì)橫向和縱向地散發(fā),從而給團(tuán)隊(duì)帶來負(fù)面的影響。

            3、這些單元測試代碼毫無用處,甚至產(chǎn)生負(fù)作用

            對(duì)于后來者來說,這種單元測試代碼沒有任何作用,因?yàn)閷懽髡弑揪褪窃诓涣私庑枨蟮幕A(chǔ)上倉促寫就的,那么自然對(duì)后來者理解需求沒有任何益處;而且如果后來者相信的這份單元測試代碼,沒有充分地調(diào)查具體的實(shí)現(xiàn)代碼,還會(huì)因此產(chǎn)生誤解。

            單元測試到底要怎么寫?何時(shí)寫?

            這是一個(gè)很值得探究的問題,但是有十足的必要。

            在網(wǎng)上上看到“如何控制單元測試的粒度”這篇文章,文章是從StackOverflow上的一個(gè)問題開始引入的。

            這個(gè)問題是:

            TDD需要花時(shí)間寫測試,而我們一般多少會(huì)寫一些代碼,而第一個(gè)測試是測試我的構(gòu)造函數(shù)有沒有把這個(gè)類的變量都設(shè)置對(duì)了,這會(huì)不會(huì)太過分了?那么,我們寫單元測試的這個(gè)單元的粒度到底是什么樣的?并且,是不是我們的測試測試得多了點(diǎn)?

            問題的最佳答案是:

            老板為我的代碼付報(bào)酬,而不是測試,所以,我對(duì)此的價(jià)值觀是——測試越少越好,少到你對(duì)你的代碼質(zhì)量達(dá)到了某種自信(我覺得這種的自信標(biāo)準(zhǔn)應(yīng)該要高于業(yè)內(nèi)的標(biāo)準(zhǔn),當(dāng)然,這種自信也可能是種自大)。如果我的編碼生涯中不會(huì)犯這種典型的錯(cuò)誤(如:在構(gòu)造函數(shù)中設(shè)了個(gè)錯(cuò)誤的值),那我就不會(huì)測試它。我傾向于去對(duì)那些有意義的錯(cuò)誤做測試,所以,我對(duì)一些比較復(fù)雜的條件邏輯會(huì)異常地小心。當(dāng)在一個(gè)團(tuán)隊(duì)中,我會(huì)非常小心的測試那些會(huì)讓團(tuán)隊(duì)容易出錯(cuò)的代碼。

            看了這個(gè)最佳答案,給人感覺對(duì)單元測試持一定的否定態(tài)度和不感冒態(tài)度。但是知道這一最佳答案的回答者是誰嗎?是Kent Beck。對(duì),正是那位極限編程、測試驅(qū)動(dòng)開發(fā)和單元測試以及JUnit的創(chuàng)造者Kent Beck。Kent Beck的答案,正好回答了單元測試該怎么寫、要寫到什么程度、何時(shí)應(yīng)該寫這幾個(gè)問題。我的一些觀點(diǎn):

            對(duì)于如何進(jìn)行單元測試,有這么幾個(gè)觀點(diǎn):

            一、單元測試的時(shí)機(jī)很重要

            無非兩種:

            一是在具體實(shí)現(xiàn)代碼之前,這就是所謂的測試驅(qū)動(dòng)開發(fā);

            二是與具體實(shí)現(xiàn)代碼同步進(jìn)行,正是大部分人采用的方式。

            那種事后單元測試,基本是沒用的。當(dāng)然有一種例外:要對(duì)沒有單元測試的既有代碼進(jìn)行維護(hù)和改造,這時(shí)候需要為既有代碼追加單元測試,但是這也得建立在充分調(diào)查理解需求的基礎(chǔ)上才能進(jìn)行。

            二、單元測試的執(zhí)行者的角色

            單元測試應(yīng)當(dāng)由具體實(shí)現(xiàn)代碼的開發(fā)者進(jìn)行,也就是說每個(gè)開發(fā)人員都應(yīng)當(dāng)同時(shí)對(duì)自己負(fù)責(zé)具體實(shí)現(xiàn)代碼和單元測試代碼負(fù)責(zé)。

            這里也存在同第一條中的例外的情況。

            三、單元測試應(yīng)當(dāng)突出重點(diǎn)

            應(yīng)當(dāng)對(duì)那些重點(diǎn)部分重點(diǎn)關(guān)照,主要有:

            1、邏輯復(fù)雜的

            2、容易出錯(cuò)的

            3、不易理解的,即使是自己過段時(shí)間也會(huì)遺忘的,看不懂自己的代碼,單元測試代碼有助于理解代碼的功能和需求

            4、后期需求變更可能性相對(duì)比較大的,這樣后期需求更變修改代碼之后就不用太擔(dān)心寫的代碼對(duì)不對(duì)以及是否破壞既存代碼邏輯了

            四、單元測試也應(yīng)注重質(zhì)量,不要寫無用的單元測試代碼

            寫沒有實(shí)際用處的單元測試不如不寫,正如注釋,寫沒有意義的注釋也不如不寫。

            最后要說的是:

            那種為了單元測試而單元測試的愚蠢行為應(yīng)當(dāng)立即停止。

            那種只是想把單元測試作為一項(xiàng)面子工程的行為更應(yīng)當(dāng)停止(官場的種種壞習(xí)慣不應(yīng)該在思想純潔的程序員當(dāng)中流行)。

            那些對(duì)單元測試沒有深入理解,只是希望今后能冠以“單元測試覆蓋率100%”榮譽(yù)頭銜的團(tuán)隊(duì),應(yīng)該立即停止這種想法。

            單元測試不應(yīng)當(dāng)過于重視覆蓋率,而應(yīng)該在需要的時(shí)候?qū)憜卧獪y試。何時(shí)寫,怎么寫,都需要建立在開發(fā)者已經(jīng)對(duì)單元測試有深刻理解的基礎(chǔ)上。

            單元測試也是一把雙刃劍,要用得好它才能發(fā)光發(fā)熱,產(chǎn)生強(qiáng)大的正能量,請(qǐng)不要把它當(dāng)作“龍泉寶劍”掛在自家的玄關(guān)辟邪。

          posted on 2013-05-10 09:41 順其自然EVO 閱讀(236) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2013年5月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 茂名市| 恩施市| 临猗县| 海丰县| 新巴尔虎右旗| 二连浩特市| 安龙县| 新沂市| 夏邑县| 合山市| 沙雅县| 普兰店市| 高唐县| 金川县| 醴陵市| 德化县| 汕尾市| 海门市| 屏边| 柳州市| 抚远县| 泸水县| 北碚区| 定陶县| 肥西县| 贺兰县| 丰城市| 额敏县| 永泰县| 盐池县| 阜新市| 壤塘县| 浙江省| 宜城市| 奇台县| 观塘区| 高平市| 盖州市| 东辽县| 吉安市| 连云港市|