在.NET開發中的單元測試工具之(2)——xUnit.Net

 

在上一篇《在.NET開發中的單元測試工具之(1)——NUnit》中講述瞭如何使用NUnit在.NET開發中進行單元測試以及NUnit的一些缺點,今天將講述如何使用xUnit.Net來進行單元測試。
xUnit.Net介紹
xUnit.net的創造者的創造者是Jim Newkirk和Brad Wilson從包括NUnit及其它單元測試框架的使用經驗中總結出來的一個新框架,相比於NUnit,xUnit.net有如下特點:
爲每個測試方法產生一個對象實例
取消了[SetUp]和[TearDown]
取消了[ExpectedException]
類似於Aspect的功能
減少了自定義屬性(Attribute)的數目
採用泛型
匿名委託
可擴展的斷言
可擴展的測試方法
可擴展的測試類
xUnit.net的官方網站是:http://xunit.codeplex.com,下面是xUnit.net的運行界面:

注意在下載的xUnit.net壓縮包內有4個支持GUI方式運行的exe文件,分別是:
xunit.gui.clr4.exe:用於在x64及.Net4.0下運行xUnit.net。
xunit.gui.clr4.x86.exe:用於在x86及.Net4.0下運行xUnit.net。
Xunit.gui.exe:用於在x64及.Net4.0以下版本運行xUnit.net。
xunit.gui.x86.exe:用於在x86及.Net4.0以下版本運行xUnit.net。
xUnit.Net下載與安裝
xUnit.Net的常用Attribute標記
如果以前使用過NUnit或者VS自帶的MSTest測試工具,下面的對比表格會讓你很容易上手xUnit.net:
NUnit 2.2
MSTest
xUnit.net
備註
[Test]
[TestMethod]
[Fact]
標記爲測試方法
[TestFixture]
[TestClass]
n/a
包含有測試方法的類,在xUnit.net中無需標記,它會查找程序集中所有的public的測試方法
[ExpectedException]
[ExpectedException]
Assert.Throws/ Record.Exception
期望拋出異常
[SetUp]
[TestInitialize]
Constructor(即構造函數)
在每個測試方法執行之前用於初始化的方法
[TearDown]
[TestCleanup]
IDisposable.Dispose
在每個測試方法執行之後用於結束的方法
[TestFixtureSetUp]
[ClassInitialize]
IUseFixture<T>
在所有測試方法執行之前用於初始化的方法
[TestFixtureTearDown]
[ClassCleanup]
IUseFixture<T>
在所有測試方法執行之後用於結束的方法
[Ignore]
[Ignore]
[Fact(Skip="reason")]
臨時忽略被標記的方法
n/a
[Timeout]
[Fact(Timeout=n)]
用於指定被測試方法的最大執行時間(單位毫秒),如果超過指定時間則會被標記爲測試失敗
[Property]
[TestProperty]
[Trait]
Set arbitrary metadata on a test
n/a
[DataSource]
[Theory], [XxxData]
xUnit.Net的斷言(Assertions)
下面的表格也是一個關於NUnit、MSTest及xUnit.Net斷言的對比。
NUnit 2.2
MSTest
xUnit.net
備註
AreEqual
AreEqual
Equal
相等比較
AreNotEqual
AreNotEqual
NotEqual
不相等比較
AreNotSame
AreNotSame
NotSame
不相同比較
AreSame
AreSame
Same
相同比較
Contains
Contains (on CollectionAssert)
Contains
DoAssert
n/a
n/a
n/a
DoesNotContain (on CollectionAssert)
DoesNotContain
n/a
n/a
DoesNotThrow
Fail
Fail
n/a
可用Assert.True(false, "message")替代
Greater
n/a
n/a
可用Assert.True(x > y)替代
Ignore
Inconclusive
n/a
n/a
n/a
InRange
IsAssignableFrom
n/a
IsAssignableFrom
IsEmpty
n/a
Empty
IsFalse
IsFalse
False
IsInstanceOfType
IsInstanceOfType
IsType
IsNaN
n/a
n/a
可用Assert.True(double.IsNaN(x))替代
IsNotAssignableFrom
n/a
n/a
可用Assert.False(obj is Type)替代
IsNotEmpty
n/a
NotEmpty
IsNotInstanceOfType
IsNotInstanceOfType
IsNotType
IsNotNull
IsNotNull
NotNull
IsNull
IsNull
Null
IsTrue
IsTrue
True
Less
n/a
n/a
可用Assert.True(x < y)替代
n/a
n/a
NotInRange
確保數據在某個範圍內
n/a
n/a
Throws
確保會拋出異常
xUnit.Net的項目文件結構
因爲在可視化方面xUnit.Net不如NUnit,所以這裏有必要介紹一下它的項目文件.xunit的組成元素。.xunit實際上也是一個xml文件,它的根節點是<xunit>,<xunit>有<assemblies>子節點,<assemblies>下可以有多個<assembly>節點。<assembly>節點包含以下屬性:
filename:這是必須屬性,用於指定包含在項目中的絕對或者相對路徑的文件。
config-filename:這個是非必須屬性,用於指定測試時所使用的config文件,默認是none,表示不適用任何配置文件。
shadow-copy:運行測試時是否對dll進行shadow-copy,默認是true,這個咱還不清楚true/false對程序的影響。
下面就是一個例子,在例子中執行指明瞭測試中使用的config文件:
 
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <xunit> 
  3.   <assemblies> 
  4.     <assembly filename="bin\Debug\XunitDemo.exe" config-filename="bin\Debug\XunitDemo.exe.config" shadow-copy="true"/> 
  5.     <assembly filename="bin\Debug\xunit.dll" shadow-copy="true" /> 
  6.   </assemblies> 
  7. </xunit> 
xUnit.Net的使用
xUnit.Net的常見用法很簡單,對於屬性NUnit的筒子們來說,輕鬆掌握xUnit.net的常見用法不在話下,下面就是一個簡單例子(實現添加了config文件並做了相應配置,詳情見本系列之一):
 
  1. using System; 
  2. using Xunit; 
  3. using System.Configuration; 
  4. namespace XunitDemo 
  5.     public class XunitDemo:IDisposable 
  6.     { 
  7.         public XunitDemo() 
  8.         { 
  9.             //在這裏可以做測試開始前的初始化工作 
  10.             System.Console.WriteLine("Init"); 
  11.         } 
  12.         [Fact] 
  13.         public void TestAdd() 
  14.         { 
  15.             Assert.Equal<int>(5, 2 + 3); 
  16.         } 
  17.         [Fact(Timeout=900)]//指定超時爲900ms 
  18.         public void TestTimeout() 
  19.         { 
  20.             System.Threading.Thread.Sleep(1000); 
  21.             Assert.InRange<double>(new Random().NextDouble()*10,5,10); 
  22.         } 
  23.         [Fact] 
  24.         public void Test0_51CTOBlog() 
  25.         { 
  26.             //不區分大小寫等值判斷 
  27.             Assert.Equal<bool>(true,string.Equals(ConfigurationManager.AppSettings["51ctoBlog"], "http://zhoufoxcn.blog.51cto.com",StringComparison.InvariantCultureIgnoreCase); 
  28.         } 
  29.         [Fact] 
  30.         public void Test0_CSDNBlog() 
  31.         { 
  32.             Assert.Equal<string>(ConfigurationManager.AppSettings["CSDNBlog"], "http://blog.csdn.net/zhoufoxcn"); 
  33.         } 
  34.         [Fact] 
  35.         public void Test0_SinaWeiBo() 
  36.         { 
  37.             Assert.Equal<string>(ConfigurationManager.AppSettings["SinaWeiBo"], "http://weibo.com/zhoufoxcn"); 
  38.         } 
  39.         public void Dispose() 
  40.         { 
  41.             //在這裏可以做測試結束後的收尾工作 
  42.             System.Console.WriteLine("Dispose"); 
  43.         } 
  44.     } 
程序運行效果如下:
 

總結
作爲NUnit的改進版,xUnit.Net確實克服了NUnit的不少缺點(關於NUnit的缺點和不足之處請見上一篇《在.NET開發中的單元測試工具之(1)——NUnit》),和NUnit的Assert API相比,xUnit.Net的Assert更精簡但是又足以滿足單元測試的需要,相比之下NUnit的Assert API略顯臃腫(這可能是跟它是從.Net1.1一直支持過來並且要保持向下兼容有關),但在GUI的易用性方面xUnit.Net不如NUnit,NUnit的GUI提供了很多配置界面,使配置工作可以通過界面設置完成,但相同的工作在xUnit.Net中則需要在項目文件中通過配置節點實現(比如指定config文件)。
此外,NUnit和xUnit.Net都在一定程度上支持VS,比如可以使用xUnit.Net同一目錄下的xunit.installer.exe來配置對VS的支持,下圖是運行xunit.installer.exe時的界面:
 

周金橋
2013-04-06

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章