用NUnit跑C#和C++的單元測(cè)試 單元測(cè)試代碼
這幾天打算用個(gè)自動(dòng)化的單元測(cè)試框架來(lái)組織一些case,因?yàn)橹坝眠^(guò)CppUnit,第一感覺(jué)是用它吧。剛好有個(gè)項(xiàng)目組做一個(gè)關(guān)于用NUnit的sharing,而且是兼容并包managed和native的case。想想可能能受到些啟發(fā),便跑去聽(tīng)了一下。
他們用的測(cè)試框架當(dāng)然是NUnit,跑C#的case自然不在話下,可是如何跑C++的case呢?不是CppUnit的改裝,而是另外一套東西,有同學(xué)已經(jīng)做出一個(gè)現(xiàn)成的工具了:GenTestAsm.,基本步驟如下:
1. 用C++寫(xiě)case,并export。
2. 解析C++ DLL文件,得到export的case
3. 自動(dòng)寫(xiě)C#代碼調(diào)用這些export的case(看著高深,可有規(guī)律的東西肯定能自動(dòng)化)
4. 編譯產(chǎn)生的assemly可以直接在NUnit里面跑了。
很酷!
順便記下幾點(diǎn):
1. NUnit和被測(cè)代碼是在同一個(gè)進(jìn)程里面,很容易由于被測(cè)代碼引起整個(gè)測(cè)試框架的crash,那么拿到終的report會(huì)有問(wèn)題。雖說(shuō)C#的case不容易crash(沒(méi)有指針?),但通過(guò)上述方法調(diào)用C++,讓它c(diǎn)rash不是件難事。所有好是能做進(jìn)程外測(cè)試。
2. NUnit使用shared copy的方法,使真正load進(jìn)來(lái)的dll并不是你編譯出來(lái)的那個(gè),而是另外拷了一個(gè),這樣在可以在不關(guān)閉NUnit的情況下rebuild被測(cè)工程。當(dāng)然,GetTestAsm也提供了Thunk DLL的技術(shù),在每個(gè)case開(kāi)始時(shí)load DLL, 結(jié)束時(shí)unload DLL,也達(dá)到了這種效果。
3. VC++中Additional Dependencies除了lib,還能加obj,這樣另外一個(gè)工程中的代碼可以直接編譯進(jìn)本工程了。這么做的目的是希望使用另外一個(gè)DLL中的未export的函數(shù)。但是因?yàn)閛bj不是同一個(gè)工程編譯出來(lái)的,一些工程設(shè)置上的不同可能會(huì)引起問(wèn)題。
4. LoadLibrary是可以load一個(gè)exe的,MSDN也說(shuō)明了 --- 我竟然以前都沒(méi)注意到。當(dāng)然,寫(xiě)一個(gè)exe純粹為了當(dāng)dll那有點(diǎn)不和諧了。我遇到過(guò)的在exe里export函數(shù),是為了在同一進(jìn)程中的插件里使用這些函數(shù)。
不錯(cuò),可以考慮一下用NUnit,這樣case既可以是C#的,也可以是C++的,比較靈活。