MSTest,NUnit 3,xUnit.net 2.0 比較

最近新專案期望使用較多的測試來保障程式品質,所以又到了要選擇相關工具的時候,首先遇到的就是測試框架 (Test Framework):MSTest,NUnit 3,xUnit.net 2.0 是比較常見的三套,尤其又以 MSTest,NUnit 3 較多人使用,雖然主要功能差不多,但終究在語法上有差異,團隊使用還是得統一,所以就來做個不負責任比較XD 本來考慮要把 MSTest 加進來比的 但還在 preview 好像不太準,也許再過幾個月再來比一次吧@@”

語法比較 - Attributes

我自己整理的比較表如下,如果有錯誤,還請各位大大指導,謝謝

MSTest (v1)NUnit 3xUnit.net 2.xComments
[AssemblyCleanup]n/an/a識別方法,該方法包含組件中的所有測試都執行完畢後,為釋放此組件所佔用資源而要使用的程式碼。
[AssemblyInitialize]n/an/a識別方法,該方法所包含的程式碼用於已執行組件中的所有測試之前,以便配置此組件所佔用的資源。
[ClassCleanup][OneTimeTearDown]IClassFixture指定測試執行後的結束方法,一個測試 class 只執行一次
[ClassInitialize][OneTimeSetUp]IClassFixture指定測試執行前的起始方法,一個測試 class 只執行一次
[CssIteration]Repeat表示這個測試所對應的專案反覆項目。
[CssProjectStructure]n/an/a表示這個測試所對應到之 Team 專案階層架構中的節點。
[DataSource][Theory][Theory]
[xxxData]”
data-driven test
[DeploymentItem]n/an/a指定應該在執行測試之前的組件一起部署的檔案或目錄。附加這個屬性對測試類別和測試方法。您可以使用多個執行個體。
[Description][Description]n/a用來指定測試的說明。
[ExpectedException]Throws.TypeOf()Assert.Throws
Record.Exception”
測試的對象出現 exception Nunit 3 與 xUnit.net 都是直接從 code 處理掉,是比較方便直覺的
[ExpectedExceptionBase]n/an/a這是屬性的基底類別,這些屬性指定單元測試應擲回預期的例外狀況。
[HostType]platform 有包含相關功該n/a指定將執行相關聯單元測試的主機的類型。
[Ignore][Ignore][Fact(Skip=“reason”)]用來標示忽略該測試
[Owner][Author]n/a用來指定負責維護、執行和/或偵錯測試的人員。
[Priority][Order]n/a用來指定單元測試的優先權。
[TestCategory][Category]n/a用來指定單元測試分類別的類別。
[TestCategoryBase]n/an/a提供分類屬性的基底類別。
[TestClass][TestFixture]n/a將 class 標示測試 class. 特別的是 xUnit.net 不需要加上這樣的 attibute 會自動去搜尋所有 public class 中的測試方法,但這樣一來也代表著速度會受到影響;
[TestClassExtension]n/an/a啟動類別,以便將其辨認為單元測試延伸模組類別。
[TestCleanup][TearDown]IDisposable.Dispose指定測試執行後的方法,常用來清除測試產生的資料,每個測試皆會執行一次
[TestInitialize][SetUp]Constructor指定測試執行前的起始方法,常用來設定測試用的初始值,每個測試皆會執行一次
[TestMethod][Test][Fact]標記為測試方法
[TestProperty][Property][Trait]用來指定共用的測試屬性
[Timeout][Timeout]n/a用來指定單元測試的逾時期間。
[WorkItem]n/an/a用來指定與測試相關聯的工作項目。
n/a[TestFixtureSource]ICollectionFixture用來與其他測試共用物件
n/a[Apartment]n/a可以使用在組件、class、method,用來指定測試執行的模式-STA(Single-threaded apartment)/MTA(Multi-threaded apartment)
n/a[Combinatorial]n/a給定參數集合,會自動產生所有參數組合的測試
n/a[Culture]n/a說明測試應該使用的語系,不會直接修改語系
n/a[Datapoint]n/a為 theory 方法提供測試資料
n/a[DatapointSource]n/a為 theory 方法提供測試資料,資料為集合或是陣列(ienumerable)
n/a[Explicit]n/a如果沒有特別選定執行,預設為不執行
n/a[LevelOfParallelism]n/a平行測試的 thread 數,組件層級的 attribute,預設值是 cpu 核心數或是2(看哪個比較大)
n/a[Maxtime]n/a指定測試最大可以執行時間(單位:毫秒),超出時間即為失敗,仍會執行結束
n/a[Pairwise]n/a會產生所有參數的兩兩對應測試組合;combinatorial 適用於兩組參數,PairwiseAttribute 則適用於兩組以上
n/a[Parallelizable]n/a用來標示哪些測試要平行執行(會影響下層),可以指定影響範圍 (None-不使用平行執行;Self-自己與其他測試使用平行執行;Choldren-所屬下層測試使用平行測試;Fixture-使用平行測試);ParallelScope.Self 是預設值;並未實作於 method 這層(ParallelizableAttribute 套用在 method 上會被忽略);ParallelScope.Children 與 ParallelScope.Fixtures 功能相同
n/a[Platform]n/a用來指定測試的平台,詳細清單可以參考 nunit GitHub
n/a[Random]n/a產生隨機參數來測試
n/a[Range]n/a將範圍內所有可能參數代入測試
n/a[RequiresThread]n/a以獨立的 thread 來執行測試
n/a[Retry]n/a失敗重試
n/a[Sequential]n/a將參數組合依序執行,而不是對所有組合執行 e.g. [a,b,c]*[1,2,3] –> a-1,b-2,c-3
n/a[SetCulture]n/a指定語言
n/a[SetUICulture]n/a指定 UI 顯示語言
n/a[SetUpFixture]n/a讓 class 在同一個 namespace 中有一次性的統一起始(setup)或是結束(teardown)行為
n/a[SingleThreaded]n/a用來將 class 中的測試方法在同個 thread 中執行,Nunit 3.6 才加入
n/a[TestCase]n/a給定測試案例參數來進行測試
n/a[TestCaseSource]n/a先定義測試案例參數,然後將參數指定給 method 來測試
n/a[TestOf]n/a用來標示是哪個 class 的測試
n/a[Values]n/a為測試方法指定參數-用在描述 method 的參數
n/a[ValueSource]n/a先定義參數資料,再指定給 method 來進行測試,可以給自訂型別 - 用在描述 method 的參數

語法比較 - Assertions

我自己整理的比較表如下,如果有錯誤,還請各位大大指導,謝謝

MSTest (v1)NUnit 3xUnit.net 2.x
AreEqualAreEqualEqual
AreNotEqualAreNotEqualNotEqual
AreNotSameAreNotSameNotSame
AreSameAreSameSame
Equalsn/aEquals
Failn/an/a
InconclusiveInconclusiven/a
IsFalseFalseFalse
IsInstanceOfTypeIsInstanceOfIsType
IsNotInstanceOfTypeIsNotInstanceOfIsNotType
IsNotNullNotNullNotNull
IsNullNullNull
IsTrueTrueTrue
ReplaceNullCharsn/an/a
n/aCatchn/a
n/aCatchAsyncn/a
n/aContainsContains
n/aDoesNotThrown/a
n/aDoesNotThrowAsyncn/a
n/aFailn/a
n/aGreatern/a
n/aGreaterOrEqualn/a
n/aIgnoren/a
n/aIsAssignableFromn/a
n/aIsEmptyEmpty
n/aIsNaNn/a
n/aIsNotAssignableFromn/a
n/aIsNotEmptyNotEmpty
n/aLessn/a
n/aLessOrEqualn/a
n/aPassn/a
n/aThrowsThrows
n/aThrowsAsyncThrowsAsync
n/an/aAll
n/an/aCollection
n/an/aDoesNotContain
n/an/aDoesNotMatch
n/an/aEndsWith
n/an/aInRange
n/an/aIsAssignableFrom
n/an/aMatches
n/an/aNotInRange
n/an/aNotStrictEqual
n/an/aProperSubset
n/an/aProperSuperset
n/an/aPropertyChanged
n/an/aReferenceEquals
n/an/aSingle
n/an/aStartsWith
n/an/aStrictEqual
n/an/aSubset
n/an/aSuperset
n/an/aThrowsAny
n/an/aThrowsAnyAsync

執行速度

使用微軟官方範例,利用三個 test framewrok 進行兩個測試

  1. 直接丟出驗證失敗
  2. 驗證值是否與預期相符
  • 測試 source code 請參考 GitHub

  • 測試結果如下

    speedcompare

其他功能

  • 有些網路文章都提到 NUnit 及 xUnit 的功能比較多,但我沒真的用過,實在無法比較,就請各位大大指導了

心得

NUnit 功能明顯多上不少,xUnit.net 的文件非常難找而且速度與 Test Explorer 的顯示都相對比較弱些,最後我選了 MSTest ,功能面透過 Visual Studio 的強化再加上套件的輔助已經足夠,但如同我前面提到的,我用到的功能不多就是了

上面整理的比較表也整理上 GitHub , 請參考 MStest_NUnit_xUnit.net_Compare

參考資料

  1. Comparing xUnit.net to other frameworks
  2. Microsoft.VisualStudio.TestTools.UnitTesting 命名空間
  3. NUnit Attibutes
  4. MStest_NUnit_xUnit.net_Compare