需要另外安裝 NUnit Project Template

單元測試的藝術 一書中,使用的是 NUnitNSubstitute,但 .NET Core SDK 預設只提供 MSTestxUnit,該如何在 .NET Core 使用我們熟悉的 NUnitNSubstitute 呢 ?

Version


macOS High Sierra 10.13.4
.NET Core 2.1
NUnit 3.10.1
NSubstitute 3.1.0
Rider 2018.1.3

Symptons


1
$ dotnet new -l
  • -l : list ,使用 dotnet new 加上 -l 參數,將列出目前系統所安裝的所有 project template。

nunit000

.NET Core SDK 預設只提供 MSTestxUnit 的 project template。

nunit001

  • 因為 .NET Core SDK 只有 MSTestXUnit,因此 Rider 也只支援 MSTestxUnit

NUnit


nunit002

事實上在 .NET Core 官網的 Available templates for dotnet new,還準備了不少其他 project template 可供下載,其中也包含了 NUnit

1
$ dotnet new -i "NUnit3.DotNetNew.Template::*"

nunit003

nunit004

  1. 安裝完就會出現 NUnit 3 project template

nunit005

  1. 安裝完後,Rider 也會出現 NUnit 3 Test Project

Project Reference


將 Class Library 的 project reference 加到 Unit Test 專案。

nunit007

  1. 選擇 Unit Test 專案
  2. 按滑鼠右鍵選擇 Add
  3. 選擇 Add Reference

nunit008

  1. 選擇 ClassLib
  2. OK 繼續

NSubstitute


除了 NUnit 外,單元測試另外一個要角就是 NSubstitute,這要另外安裝。

nunit009

  1. 選擇 Unit Test 專案
  2. 按滑鼠右鍵選擇 Manage NuGet Packages

nunit006

  1. 在 NuGet 下輸入 NSubstitute
  2. 選擇 NSubstitute
  3. 在 Unit Test 專案下安裝 NSubstitute

Parallel Test


NUnit 預設並不是以 parallel 進行單元測試,而是以 sequential 方式,也就是 一個單元測試執行完,才會進行下一個單元測試,而不是每個單元測試平行執行。

這種方式雖然安全,但有幾個缺點:

  1. 執行速度較慢,沒有完全發揮多核心 CPU 的優勢
  2. Jenkins 會以 parallel 方式執行單元測試,因此每個單元測試之間不能相依,讓本機與 Jenkins 環境相同

AssemblyInfo.cs

1
2
3
using NUnit.Framework;

[assembly:Parallelizable(ParallelScope.All)]

在 Unit Test 專案下新增 AssemblyInfo.cs,對整個 Unit Test assembly 增加 NUnitParallelizable attribute,如此每個 test method 都會以 parallel 方式執行單元測試。

nunit010

Conclusion


  • .NET Core SDK 預設沒有支援 NUnit,但只要自行透過 dotnet new -i,即可安裝 NUnit project template
  • NSubstitute 以 NuGet package 形式存在,必須另外安裝
  • NUnit 預設以 sequential 方式執行 Unit Test,不僅沒發揮多核心 CPU 威力,也與 Jenkins 執行環境不同,建議在 Unit Test 專案增加 AssemblyInfo.cs,對整個 Unit Test assembly 增加 Parallelizable(ParallelScope.All) attribute,如此才會以 parallel 方式執行單元測試,也能提早發現 test method 彼此相依可能造成的問題

Sample Code


完整的範例可以在我的 GitHub 上找到