Testing 的第一個(gè)切入點(diǎn):單元測試。
本篇文章將針對(duì)單元測試進(jìn)行簡介,主要內(nèi)容包含了5W:
而How 的部分,屬于實(shí)現(xiàn)部分,將于下一篇文章介紹工具與簡單的范例。
最后會(huì)提到測試用例所代表的意義與其重要性。
單元測試,是開發(fā)人員最該寫的測試程序,卻也是最容易被忽略的測試。
大家常碰到的測試相關(guān)問題是:
看完這幾篇單元測試的相關(guān)文章后,希望大家可以獲得一些想法,解決這些問題。
先舉幾個(gè)在開發(fā)上常見的問題:

這些問題,可以有哪些Unit Test 相關(guān)的方式來解決:

總而言之,沒有被測試涵蓋到的程序,即使它可能是對(duì)的,也沒人敢拍胸脯保證。而有了測試用例來輔助說明與保護(hù),至少可以拍胸脯保證,在這樣的測試用例下,這個(gè)對(duì)象的設(shè)定,肯定如同預(yù)期般執(zhí)行。
而單元測試可以提供回歸測試的保護(hù),在每一次異動(dòng)完程式,可以單鍵執(zhí)行就知道是否破壞了原本對(duì)對(duì)象行為的預(yù)期。
單元測試可以透過一些輔助設(shè)計(jì),來達(dá)到與外部環(huán)境、服務(wù)、相依隔絕,而僅測試該物件本身的邏輯,以及與外部的互動(dòng)是否符合預(yù)期。
造成問題的測試案例,往往是最珍貴的,因?yàn)樽罹叽硇裕沧罹邇r(jià)值。因?yàn)樗峁┝宋覀冃拚齜ug的方向以及指標(biāo)。而針對(duì)發(fā)生問題的測試案例,來執(zhí)行單元測試,馬上就可以知道是否是該對(duì)象的內(nèi)部問題。
最后,單元測試由于具備與外界服務(wù)、相依隔絕的特性,所以可以幫助撰寫實(shí)際的對(duì)象時(shí),具有可測試性、低耦合性,彼此之間只相依于抽象或接口。進(jìn)而通過IoC 的設(shè)計(jì),讓我們可以做到關(guān)注點(diǎn)分離,讓開發(fā)各個(gè)對(duì)象的developer,可以透過接口來溝通,不相依于彼此實(shí)現(xiàn),就能平行開發(fā)。
Unit Test 的定義與基本準(zhǔn)則,如下圖所示:

Unit Test的特性,一個(gè)字:FIRST。如下圖所示:

即:優(yōu)良的單元測試具有以下的特點(diǎn):簡稱為 A-TRip。
- 自動(dòng)性(Automatic)
 - 完備性(Thorough)
 - 可重復(fù)性(Repeatable)
 - 獨(dú)立性(Independent)
 - 專業(yè)性(Professional)
 
單元測試的覆蓋范圍,以定義來說,單元測試是最小的測試單位,在面向?qū)ο笾校褪菧y試一個(gè)方法。而方法一定會(huì)在某個(gè)對(duì)象上(即使是靜態(tài)方法,也是在類型對(duì)象上)。
所以,單元測試通常就只關(guān)注在測試的目標(biāo)對(duì)象上,而不管目標(biāo)對(duì)象以外的東西,例如:目標(biāo)對(duì)象所相依的實(shí)體對(duì)象、相依服務(wù)、相依資源、相依環(huán)境等等...
單元測試,簡單的說,就是用來模擬外部如何使用這個(gè)目標(biāo)對(duì)象,或是如何與這個(gè)目標(biāo)對(duì)象互動(dòng)。所以我們所撰寫的單元測試程序,就是模擬與目標(biāo)對(duì)象互動(dòng)的程序。測試案例,就是該互動(dòng)下的情境。接著驗(yàn)證物件的行為是否符合我們預(yù)期。
因此,單元測試程式,既然是模擬外部如何使用目標(biāo)物件,所以也只會(huì)針對(duì)目標(biāo)對(duì)象對(duì)外開放的方法。
而基本上,單元測試透過哪些方式去驗(yàn)證對(duì)象的行為符合預(yù)期呢?簡單來說,有三種:



單元測試該由誰來撰寫,就如同前言所說,最應(yīng)該撰寫的是developer,而非QA/QE。
就如Where段落所說,單元測試簡單的說,是我們?cè)谠O(shè)計(jì)對(duì)象的時(shí)候,預(yù)期外部該如何使用這個(gè)對(duì)象,進(jìn)而衍生出對(duì)象該提供什么樣的功能、具備什么樣的行為。正因?yàn)閷?duì)象的設(shè)計(jì)人、使用人,都是developer,所以單元測試的程式,當(dāng)然由developer來設(shè)計(jì),最為妥當(dāng)。尤其由用的人來寫,最為精準(zhǔn)。
歸納幾個(gè)基本要點(diǎn):
撰寫單元測試的時(shí)機(jī)點(diǎn),簡單??分成三個(gè):
想清楚,外部的需求是什么,才能設(shè)計(jì)出符合需求的對(duì)象。
當(dāng)需求異動(dòng)時(shí),自然需要針對(duì)新的需求,來設(shè)計(jì)新的測試程序,因?yàn)檫@樣才能驅(qū)使目標(biāo)物件行為的改變。
當(dāng)出現(xiàn)非預(yù)期的執(zhí)行結(jié)果時(shí),通常代表目標(biāo)物件有著非預(yù)期的行為發(fā)生,有可能是當(dāng)初測試案例不足,所以要增加我們的「預(yù)期」。
也有可能是當(dāng)初預(yù)期的結(jié)果就錯(cuò)了,那其實(shí)就可以當(dāng)作是第二點(diǎn),需求的異動(dòng)。(當(dāng)然對(duì)使用端來說,還是屬于bug,但對(duì)對(duì)象設(shè)計(jì)來說,測試案例方向就錯(cuò)了)
大家買過3C產(chǎn)品或電器吧,基本上拿到一個(gè)東西,我們都會(huì)先看使用說明書。
大家肯定也寫過一堆「系統(tǒng)分析書」、「代碼規(guī)格書」、「SA/SD 文件」等等...但這些文件,跟最后線上的代碼,究竟有多少是相同的呢?文件越詳細(xì),代表后面修改的effort 越大。
因?yàn)檐浖O(shè)計(jì),本來就是個(gè)需求頻繁變動(dòng)的過程,往往大家只想「凍結(jié)需求」,卻很常因?yàn)椤竷鼋Y(jié)需求」搞到作出來的系統(tǒng)難用,因?yàn)椴环鲜褂谜咝枨蟆?/p>
我們期望的是,每一次的需求異動(dòng),都是軟??件進(jìn)化的動(dòng)力,每一次的異動(dòng),都是品質(zhì)的累積,以及更符合使用者的需求。
而文件呢?只有一開始分析、設(shè)計(jì)爽的,因?yàn)榇a寫下去,跟文件搭不搭的起來,只有三個(gè)人知道,一個(gè)已經(jīng)離職了,一個(gè)是我,另一個(gè)我不能說。
鮮少會(huì)有文件跟著代碼一直進(jìn)行更新的。
但文件卻又是輔助了解與說明很重要的東西,那怎么辦?很簡單,會(huì)一直活著的,就只有代碼。要驗(yàn)證代碼是否符合我們預(yù)期,最簡單的方式,就是用代碼驗(yàn)證它的行為,一翻兩瞪眼,現(xiàn)在的物件究竟?jié)M足了那些功能,哪些情境下可以跑出預(yù)期結(jié)果,測試案例一目了然。
所以,測試案例的意義與價(jià)值是什么?
代碼即文件,高興什么時(shí)候產(chǎn)生文件,就什么時(shí)候產(chǎn)生,保證即時(shí)、可運(yùn)作、童叟無欺。測試案例上面有的,肯定work,而測試案例上面沒有的,不一定會(huì)錯(cuò),但不打包票。
一句話總結(jié):「Working software is based on working test cases」。
Working software 是TDD 的整個(gè)骨架,也是user 最需要的東西。
備注:這個(gè)系列是我畢業(yè)后時(shí)隔一年重新開始進(jìn)入開發(fā)行業(yè)后對(duì)大拿們的博文摘要整理進(jìn)行學(xué)習(xí)對(duì)自我的各個(gè)欠缺的方面進(jìn)行充電記錄博客的過程,非原創(chuàng),特此感謝91 等前輩
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注