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