在上一篇《在.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 | 在所有测试方法执行之前用于初始化的方法 |
[TestFixtureTearDown] | [ClassCleanup] | IUseFixture | 在所有测试方法执行之后用于结束的方法 |
[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&#xff0c;所以这里有必要介绍一下它的项目文件.xunit的组成元素。.xunit实际上也是一个xml文件&#xff0c;它的根节点是
filename&#xff1a;这是必须属性&#xff0c;用于指定包含在项目中的绝对或者相对路径的文件。
config-filename&#xff1a;这个是非必须属性&#xff0c;用于指定测试时所使用的config文件&#xff0c;默认是none&#xff0c;表示不适用任何配置文件。
shadow-copy&#xff1a;运行测试时是否对dll进行shadow-copy&#xff0c;默认是true&#xff0c;这个咱还不清楚true/false对程序的影响。
下面就是一个例子&#xff0c;在例子中执行指明了测试中使用的config文件&#xff1a;
xUnit.Net的使用
xUnit.Net的常见用法很简单&#xff0c;对于属性NUnit的筒子们来说&#xff0c;轻松掌握xUnit.net的常见用法不在话下&#xff0c;下面就是一个简单例子&#xff08;实现添加了config文件并做了相应配置&#xff0c;详情见本系列之一&#xff09;&#xff1a;
using System;
using Xunit;
using System.Configuration;
namespace XunitDemo
{public class XunitDemo:IDisposable{public XunitDemo(){//在这里可以做测试开始前的初始化工作System.Console.WriteLine("Init");}[Fact]public void TestAdd(){Assert.Equal
}
程序运行效果如下&#xff1a;
总结
作为NUnit的改进版&#xff0c;xUnit.Net确实克服了NUnit的不少缺点&#xff08;关于NUnit的缺点和不足之处请见上一篇《在.NET开发中的单元测试工具之(1)——NUnit》&#xff09;&#xff0c;和NUnit的Assert API相比&#xff0c;xUnit.Net的Assert更精简但是又足以满足单元测试的需要&#xff0c;相比之下NUnit的Assert API略显臃肿&#xff08;这可能是跟它是从.Net1.1一直支持过来并且要保持向下兼容有关&#xff09;&#xff0c;但在GUI的易用性方面xUnit.Net不如NUnit&#xff0c;NUnit的GUI提供了很多配置界面&#xff0c;使配置工作可以通过界面设置完成&#xff0c;但相同的工作在xUnit.Net中则需要在项目文件中通过配置节点实现&#xff08;比如指定config文件&#xff09;。
此外&#xff0c;NUnit和xUnit.Net都在一定程度上支持VS&#xff0c;比如可以使用xUnit.Net同一目录下的xunit.installer.exe来配置对VS的支持&#xff0c;下图是运行xunit.installer.exe时的界面&#xff1a;
周金桥
2013-04-06