IntelliTest实战直通车(上集)
IntelliTest前世今生
??IntelliTest的前身是微軟研究院的白盒測(cè)試框架Pex,當(dāng)時(shí)的Pex并未集成到Visual Studio中,開發(fā)者需要單獨(dú)下載和配置,在下載時(shí)會(huì)附帶一個(gè)叫Moles的隔離框架(它更早些的名字叫Stubs)。隨著Visual Studio 2015 RC 版本的發(fā)布,Pex集成到Visual Studio中,成了IntelliTest,而Moles也升級(jí)成了Microsoft Fakes。
傳統(tǒng)單元測(cè)試
??回憶一下,寫單元測(cè)試之前,我們的開發(fā)流程一般是怎樣一個(gè)過(guò)程。
“我們很忙,一直忙著開發(fā)開發(fā),眼看就要到deadline了,加緊繼續(xù)開發(fā)開發(fā)。在這種情況下的產(chǎn)品質(zhì)量可想而知,于是耐心的測(cè)試給我們報(bào)bug,善良的用戶給我們提意見,沒辦法,要吃飯啊,我們又去改代碼,然而代碼并不是你想改,想改就能改的啊,為了少改出問題,往往要delay-delay-再delay。于是就陷入了一個(gè)我們寫的代碼越多,問題越多,delay也越嚴(yán)重的怪圈”
終于,在delay了28次后,我們爆發(fā)了,我們要它,對(duì),就是它,單元測(cè)試!我們要寫單元測(cè)試!
于是乎,我們的開發(fā)流程變成了類似下面這個(gè)樣子:
多美好啊,開發(fā)效率高,交互質(zhì)量也高,大家有飯吃,大家都開心(測(cè)試:“我XXX”)。
“咳咳!干啥呢!干啥呢!意淫個(gè)毛線啊,這個(gè)版本發(fā)了嗎!看看覆蓋率才多少!”
好吧,回到現(xiàn)實(shí)。
??我們確實(shí)有開始寫單元測(cè)試,也有做一些努力,但遠(yuǎn)遠(yuǎn)不夠。我們針對(duì)相對(duì)穩(wěn)定的公共組件,做了30%-50%的覆蓋率,但是對(duì)上層相對(duì)復(fù)雜的業(yè)務(wù)邏輯幾乎為0。而容易出問題,需要經(jīng)常變更的,也恰恰是這些上層業(yè)務(wù)邏輯。這些業(yè)務(wù)代碼可能經(jīng)常變更,用例也需要隨之變更,維護(hù)成本相對(duì)更高(雖然寫了單元測(cè)試會(huì)降低維護(hù)成本,但這恰恰是多數(shù)開發(fā)者很難跨越的坎兒)。
IntelliTest
IntelliTest可以做什么?
IntelliTest通過(guò)探測(cè)你的.NET代碼,自動(dòng)生成一組高覆蓋率的測(cè)試用例。雖然開發(fā)人員還是需要手動(dòng)編寫單元測(cè)試,但是IntelliTest可以確保對(duì)代碼進(jìn)行了充分的測(cè)試。
中文都能看懂,操作呢?
??再回憶一下,我們是不是經(jīng)常遇到這樣的情況:為了覆蓋不同的分支語(yǔ)句,我們需要寫多個(gè)用例,然而這些用例中很多代碼都是一樣,每次都要做相同的arrange,相同的action,甚至相同的assert。對(duì)的,你可能會(huì)說(shuō),“NUnit已經(jīng)提供了解決這個(gè)問題的方法啊,而且超級(jí)簡(jiǎn)單”,確實(shí),在NUnit中,我們可以這樣寫用例:
[TestCase(12, 3, 4)] [TestCase(12, 2, 6)] [TestCase(12, 4, 3)] public void DivideTest(int n, int d, int q) {Assert.AreEqual(q, n / d); }但是MSTest沒有這么簡(jiǎn)單的方法啊,MSTest有的只是DataSource,而這又跟IntelliTest有什么關(guān)系呢?還真有那么點(diǎn)兒關(guān)系,MSTest雖然沒有提供多參數(shù)的用例支持,但是隨著IntelliTest的推出,提供了Parameterized Unit Tests[PUT](參數(shù)化單元測(cè)試),通過(guò)PUT,IntelliTest會(huì)自動(dòng)為我們生成不同輸入?yún)?shù)的用例,而且保證每個(gè)用例都是有意義的。
??除此之外,IntelliTest能夠在你修改了業(yè)務(wù)代碼的情況下快速生成新的測(cè)試用例,大大減輕了測(cè)試用例的維護(hù)。同時(shí)這些測(cè)試用例都可以保存下來(lái),供后續(xù)回歸測(cè)試使用。
一個(gè)具體的栗子
有如下代碼:
/// <summary> /// 判斷一個(gè)文件是否包含指定后綴 /// </summary> /// <param name="fileName"></param> /// <param name="suffix"></param> /// <returns></returns> public static bool IsSuffix(string fileName, string suffix) {var fileNameLower = fileName.ToLower();if (fileNameLower.EndsWith(suffix))return true;return false; }我們右擊它選擇運(yùn)行IntelliTest,接下來(lái)會(huì)彈出一個(gè)IntelliTest結(jié)果窗口,它是長(zhǎng)下面這個(gè)樣子滴:
解釋一下各個(gè)名詞的意思:
- 塊(blocks):已覆蓋Block數(shù)/IntelliTest探測(cè)到的總Block數(shù)(Block是啥?)
- 斷言(asserts):PUT中運(yùn)行過(guò)的斷言數(shù)/PUT中定義的所有斷言數(shù)
- 運(yùn)行(runs):探測(cè)期間,IntelliTest嘗試運(yùn)行的次數(shù)
在運(yùn)行結(jié)果窗口中我們看到,IntelliTest為我們生成了9個(gè)用例,其中4個(gè)通過(guò),5個(gè)失敗,并且給出了失敗原因。點(diǎn)擊每一條用例,在右側(cè)會(huì)有此用例更加詳細(xì)的信息(包括詳細(xì)的參數(shù)和調(diào)用堆棧),便于我們跟蹤分析錯(cuò)誤原因。
??全選后保存,IntelliTest自動(dòng)添加一個(gè)測(cè)試工程并將用例放到PUT文件下面的g.cs文件中,后續(xù)可以繼續(xù)利用這些用例做測(cè)試。實(shí)際上,微軟并不希望我們編輯g.cs文件,在每次運(yùn)行IntelliTest時(shí),它會(huì)更新g.cs文件至最新。
??多次提到PUT,有必要鄭重介紹一下它了。所謂的“參數(shù)化單元測(cè)試”,指的是可以定義多組參數(shù)的單元測(cè)試方法。(哇,好鄭重啊!),是的,就是這么簡(jiǎn)單直白。通過(guò)查看IntelliTest生成的文件很容易發(fā)現(xiàn),在g.cs中的每一個(gè)用例最終都是通過(guò)調(diào)用PUT來(lái)實(shí)現(xiàn)測(cè)試的,這就是IntelliTest的參數(shù)化。在 傳統(tǒng)單元測(cè)試 部分提到的NUnit的多參數(shù)測(cè)試就是NUnit的參數(shù)化單元測(cè)試,但是IntelliTest為我們實(shí)現(xiàn)了自動(dòng)化。
??然而,現(xiàn)實(shí)總是比想象復(fù)雜,我們的業(yè)務(wù)代碼也遠(yuǎn)比栗子難嚼。在開發(fā)中使用IntelliTest會(huì)遇到的問題遠(yuǎn)比栗子中多,比如本篇未提到的IntelliTest結(jié)果窗口中的異常。IntelliTest的更多問題,下集繼續(xù)。
date: 2017-10-29 09:02:23
轉(zhuǎn)載于:https://www.cnblogs.com/erdao/p/8419765.html
總結(jié)
以上是生活随笔為你收集整理的IntelliTest实战直通车(上集)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么对开发者很重要?
- 下一篇: Scrapy爬虫-win7下创建运行项目