作為軟體品質保證的重要一環,測試程式碼涵蓋範圍是評判單元測試的重要標準。既然已經為你的代碼編寫了自動迴歸的單元測試,你當然想知道是不是所有的代碼都測到了,完整的測試程式碼涵蓋範圍可以說是零缺陷軟體的決定性因素之一。
說到.net下的代碼覆蓋統計軟體,當屬NCover大名鼎鼎了,我們將其和NAant,Nunit一起配合使用,在每日構建和自動化測試領域是非常方便的,正如我前面所說的,對許多程式員而言,還是整合到一起比較方便使用,方便快捷地調用我想要的功能。因此,我將Ncover整合到了我的Nunit中。
由於現在的開發還是基於fw1.1,所以我也只用版本較低的NCover1.3.3,目前使用倒是沒發現什麼問題。不知道什麼原因,在NCover的網站上沒有找到1.3版的原始碼,我只有反編譯一下用,畢竟直接分析和修改源碼還是方便很多。在NCover體系內,最重要的組件是Coverlib.dll,他是一個com組件,需要用regsvr32進行註冊使用,當然如果你使用安裝包,會自動進行安裝的。
那麼.net部分做了些什麼呢?看看我調用Ncover實現功能的代碼:
ProfilerSettings ps = new ProfilerSettings();
ps.CommandLineExe = "nunit-console.exe";
ps.CommandLineArgs = this._testLoader.TestFileName;
ps.CoverageFile = Path.Combine(new FileInfo(this._testLoader.TestFileName).Directory.FullName,"coverage.xml");
ProfilerDriver driver1 = new ProfilerDriver(ps);
driver1.Start();
driver1.WaitForExit();
System.Diagnostics.Process.Start(ps.CoverageFile);
NCover必須要傳入一個可執行檔來進行檢查哪些代碼被調用了,被檢查的引用組件必須有pdb調試檔案,否則是不分析。在上面的代碼中,我傳入nunit的控制台程式,讓他跑一遍當前的測試dll,然後設定輸出檔案到被測試的組件的目錄下,開啟nunit-console進程,待進程結束後,就會有一個converage.xml檔案產生,瀏覽此檔案就能看到統計結果。
這中間都發生了什麼,究竟是誰完成了這一切?.net部分的代碼也沒什麼特別的地方:
public void Start()
{
ProcessStartInfo info1 = new ProcessStartInfo(this._ps.CommandLineExe, this._ps.CommandLineArgs);
info1.UseShellExecute = false;
info1.ErrorDialog = false;
info1.CreateNoWindow = true;
info1.RedirectStandardOutput = true;
info1.RedirectStandardInput = true;
info1.RedirectStandardError = true;
if (this._ps.WorkingDirectory != null)
{
info1.WorkingDirectory = this._ps.WorkingDirectory;
}
this.SetEnvironment(info1.EnvironmentVariables);
this._proc = Process.Start(info1);
}
我對ncover的代碼作了些改動,使新進程在後台運行,否則一運行nunit-console就彈出來一個命令列,很是不爽。從上面的代碼可以看出系統僅僅設定了下進程初始狀態和環境變數,就完成了覆蓋統計和xml檔案產生。來看看環境變數的配置代碼:
private void SetEnvironment(StringDictionary env)
{
env["Cor_Enable_Profiling"] = "1";
env["Cor_Profiler"] = "CvrLib.CoverageProfiler";
env["CoverageAssemblies"] = this._ps.Assemblies;
env["CoverageLog"] = this._ps.LogFile;
env["CoverageXml"] = this._ps.CoverageFile;
if (this._ps.Debug)
{
env["CoverageDebug"] = "1";
}
if (this._ps.VerboseLog)
{
env["CoverageVerbose"] = "1";
}
if (this._ps.DisableSetIL)
{
env["CoverageDisableSetIL"] = "1";
}
if (this._ps.JITLog)
{
env["CoverageLogJit"] = "1";
}
if (this._ps.NoLog)
{
env["CoverageNoLog"] = "1";
}
}
其實這部分代碼就是把相關變數存起來,好讓真正的負責人-ConverLib.dll來進行處理。ConverLib.dll負責根據環境變數的值來進行代碼的跟蹤和記錄,產生相關的XML檔案。為了使xml更可讀,需要把一個xsl檔案也自動拷過去。
最後,我們在tools菜單上添加一項查看程式碼涵蓋範圍報表: