NUnit详细使用方法2
- 格式:doc
- 大小:299.50 KB
- 文档页数:35
NUnit使⽤详解(⼀)NUnit是⼀个单元测试框架,专门针对于.NET来写的,它是是xUnit的⼀员。
NUnit完全由C#语⾔来编写,并且编写时充分利⽤了许多.NET的特性,⽐如反射,客户属性等等.最重要的⼀点是它适合于所有.NET语⾔.单元测试:作为程序员在开发过程中,不可避免地要对软件的类及其⽅法进⾏测试。
在Web页⾯的测试过程中,好多朋友喜欢把测试结果使⽤Response.Write()显⽰在页⾯上。
⽽在类库组件的开发时,由于没有可视化界⾯,有时不得不为该类库添模⼀个测试的项⽬(Console,WinForm,等),在该项⽬中调⽤类库组件的功能,以查看测试结果。
上⾯这种测试不是我们推荐的⽅法,因为我们在测试的时候应遵循以下原则:尽量不要破坏原有的代码结构,即不要在原代码中添加⼀些冗余的测试代码。
测试模块应尽可能完整地展现测试结果。
测试模块不应⽤完即扔掉,要保存以备后续的维护测试。
⼀、NUnit运⾏界⾯《图1》在右边有⼀个进度条,如果所有测试案例运⾏成功,就为绿⾊,反之如果有⼀个不成功,则为红⾊,但也有黄⾊的.绿⾊描述⽬前所执⾏的测试都通过黄⾊意味某些测试忽略,但是这⾥没有失败红⾊表⽰有失败左边的树状⽬录是我们们编写的每⼀个测试单元。
底部的状态条状态:当所有测试完成时,状态变为Completed.运⾏测试中,状态是Running: <test-name>Test Cases:说明加载的程序集中测试案例的总个数。
这也是测试树⾥叶⼦节点的个数。
Tests Run:已经完成的测试个数。
Failures:到⽬前为⽌,所有测试中失败的个数.Time:显⽰运⾏测试时间(以秒计)⼆、在VS2008中配置NUnit进⾏测试1.新建⼀个类库项⽬。
2.在解决⽅案中的项⽬图标上右击,选择“属性”。
3.点击左边的“调试”标签4.在“启动操作”中选择“启动外部程序”,并指明NUnit程序的运⾏路径。
5.在启动选项中的“⼯作⽬录”下,指明当前类库项⽬的DLL⽂件的所在路径。
通过命令行方式使用NUnit进行UT极限编程( XP )越来越进入程序员的眼球,TD D(Test Drived Design)也越来越普及,UT( Unit Test ing)是TDD 的第一步,主要面向的是一线的开发人员,而不是项目经理、系统设计与分析人员甚至是测试人员,当然UT的一些方法也可以用于后续的测试,但从极限编程(XP)越来越进入程序员的眼球,TD D(Test Drived Design)也越来越普及,UT(Unit Test ing)是TDD的第一步,主要面向的是一线的开发人员,而不是项目经理、系统设计与分析人员甚至是测试人员,当然UT的一些方法也可以用于后续的测试,但从概念上来讲那已经不算UT了。
UT是“开发者写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确”。
xUnit系列是专门用户UT的框架(工具),包含了对目标代码进行UT的类库。
NUnit 是xUnit系列成员之一,用于对.NET Framework下的语言(实际上只要符合CTS规范的语言NUnit都支持)所写的代码进行UT。
UT的主要目的是提高代码的健壮性和提高代码的生产效率,NUnit 就是以此为初衷进行设计的,所以对于使用 IDE开发而言,添加一下nunit.framework.dll的引用就可以直接在工程中进行单元测试,引用细节由IDE本身来执行,对程序员来讲是透明的。
如果没有使用等大型IDE的,比如使用编辑器+SDK+命令行的方式进行编码,或者干脆就使用Emacs,这时很多事情就要手动进行了,这一过程可能有些boring,这也是没办法的事情,因为编辑器+命令行本来生产力就不高,但确是学习的好方式(也是我喜欢的方式)。
这里,如果被测试代码和测试代码写在不用的源文件里,进行一次UT典型步骤如下(以C#为例并假设两个文件分别为target.cs 和test.cs):·编译被测试代码为DLL或者Module:csc /t:library target.cs 或者csc /t:module target.cs·编译测试文件为DLL,并添加对外部库文件nunit.framework.dll和target.dll的引用:csc /t:library /r:c:\progra~1\nunit2~1.2\bin\nunit.framework.dll;target.dll test.cs或者只添加对外部库文件nunit.framework.dll的引用并添加target模块:csc /t:library /r:c:\progra~1\nunit2~1.2\bin\nunit.framework.dll/addmodule:module test.cs·NUnit命令行:nunit-console test.dll或者运行NUnit GUI打开test.dll,进行测试,生成测试报告。
单元测试工具Nunit基本用法1. 单元测试Unit Test :开发者编写的一小段代码,用于检验被测代码的一个很小的,很明确的功能是否正确。
2. 单元测试的具体表现:用于判断某个特定条件或场景下某个特定函数或方法的行为。
3. 单元测试的目的:为了证明某段代码的行为确实和开发者所期1. 单元测试Unit Test:开发者编写的一小段代码,用于检验被测代码的一个很小的,很明确的功能是否正确。
2. 单元测试的具体表现:用于判断某个特定条件或场景下某个特定函数或方法的行为。
3. 单元测试的目的:为了证明某段代码的行为确实和开发者所期望的一致。
4. 单元测试的核心内涵:这个简单有效的技术就是为了令代码变得更加完美。
5. NUint中的断言Assert类的静态方法:1)AreEqualsAssert.AreEqual(expected, actual[, string message])//expected:期望值(通常是硬编码的);//actual:被测试代码实际产生的值;//message:一个可选消息,将会在发生错误时报告这个消息。
因计算机并不能精确地表示所有的浮点数,所以在比较浮点数时(float或double),需要指定一个额外的误差参数。
Assert.AreEqual(expected, actual, tolerance[, string messag e])//tolerance:指定的误差,即只要精确到小数点后X位就足够了。
//例如:精确到小数点后4位Assert.AreEqual(0.6667, 0.0/3.0, 0.0001);2)IsNullAssert.IsNull(object[, string message])//是nullAssert.IsNotNull(object[, string message])//非null3)AreSameAssert.AreSame(expected, actual[, string message])//验证expected和actual两个参数是否引用一个相同的对象。
科技信息2008年第24期SCIENCE &TECHNO LO GY INFORMATION 在程序设计的过程中有许多种测试,单元测试只是其中一种。
单元测试并不能保证程序是完美无缺的,但是在所有的测试中,单元测试是第一个环节,也是最重要的一个环节。
一、什么是单元测试单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小、很明确的功能是否正确。
通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。
二、为什么要使用单元测试我们在编写代码时,总是会反复调试保证它能够通过编译。
但通过编译,只能说明它的语法正确,却无法保证它的语义也一定正确。
1.单元测试可以减少程序的BUG要减少软件中的B UG 数量,方法之一就是拥有一个专业的测试组,其工作就是尽一切可能使软件崩溃。
但不幸的是,目前大多专业测试组做的都是功能测试、系统测试。
软件界有句俗语:“开发人员不应该测试自己写的代码”。
尽管这句话很有道理,但如果开发人员不对自己的代码进行测试,怎么知道代码是否按照预期的方式运行呢。
因此,对于我们不能保证正确的函数、方法不妨进行单元测试。
2.提高开发速度一般都认为单元测试会浪费时间,其实这是一个误区。
一旦编码结束,开发人员便迫不及待的进行软件的集成工作。
这从表面上看是一项进步,其实不然。
在这种开发步骤中,系统能够正常运行的可能性很小,更多的情况是充满了各种各样的BUG 。
发现软件错误的情况有很多:由开发人员发现;由尝试运行代码的开发人员发现;由测试人员发现;由最终用户发现。
如果在第一种情况下发现软件错误,则修复错误比较容易,成本也很低。
情况越靠后,修复软件错误的成本就越高;修复一个由最终用户发现的软件错误可能要耗费100或1000倍的成本。
如果开发能够在编写代码期间发现所有的软件错误,那是再好不过了。
为此,我们就必须编写能在编写代码时能运行的测试,单元测试正好可以做到这一点。
3.编写单元测试代码的过程其实就是设计程序的过程在编写单元测试代码时,我们实际上是在思考我们的代码根据预期会返回什么的结果,它其实就是程序设计的过程。
NUnit使用介绍一、如何编写测试类a)将测试类标记为TestFixtureb)将需要测试的方法标记为Testc)选择性测试某方法或类,可将其标记为Explicitd)不想进行测试的方法,则可标记为Ignoree)不同分类的方法可用Category标记f)方法会预期发生异常,则标记为ExpectedExceptiong)测试时共享资源的初始化,可将资源的初始化代码放置于标记为Setup的方法体中h)释放资源或确保没有遗留,将代码写入标记为TearDown的方法体中i)只初始化一次,则方法标记为TestFixtureSetupj)与TestFixtureSetup匹配,释放资源用TestFixtureTearDown例:///<summary>///需测试的类///</summary>[TestFixture]public class NumersFixture{private int a;//共享资源private int b;//共享资源///<summary>/// TestFixtureSetUp 只初始运行一次///</summary>[TestFixtureSetUp]public void OpenConnection(){Console.Out.Write("open the connection to the database");}///<summary>/// TestFixtureTearDown 释放资源///</summary>[TestFixtureTearDown]public void CloseConnection(){Console.Write("close the connection to the database");}///<summary>///共享资源的初始化///</summary>[SetUp]public void init(){a = 1;b = 2;}///<summary>/// Test 标记需测试的方法///</summary>[Test]public void MultiplyTwoNumbers(){int product = a * b;Assert.AreEqual(product, 2);}///<summary>/// Category 标记同类的方法///</summary>[Test][Category("Numbers")]public void AddTwoNumbers(){int sum = a + b;Assert.AreEqual(sum, 3);}///<summary>/// Explicit 选择性测试,自动测试时忽略,可手动测试///</summary>[Test,Explicit][Category("Numbers")]public void DiminishNumbers() {int diminish = a - b;Assert.AreEqual(diminish, -1);}///<summary>/// ExpectedException 预期发生的异常///</summary>[Test][Category("Exception")][ExpectedException(typeof(DivideByZeroException))]public void DivideByZero(){int zero = 0;int infinity = a / zero;Assert.Fail("Should have gotten an exception");}///<summary>/// Ignore 不想进行测试的方法///</summary>[Test][Ignore("IgnoreMethod is ignored")]public void IgnoreMethod(){Console.Write("IgnoreMethod is ignored");}///<summary>/// TearDown 释放资源///</summary>[TearDown]public void clear() {a = 0;b = 0;}}二、在VS中应用NUnit 测试,如下配置即可:右键解决方法->属性->调试,将启动操作改为:启动外部程度,指向NUnit 的启动文件的路径C:\Program Files (x86)\NUnit 2.6.4\bin\nunit-x86.exe。
在NUnit中,断言是单元测试的核心。
NUnit提供了一组丰富的断言,这些断言是Assert类的静态方法。
如果一个断言失败,方法的调用不会返回值,并且会报告一个错误。
如果一个测试包含多个断言,那些紧跟失败断言的断言都不会执行,因此,通常每个测试方法最好只有一个断言。
Assert类提供了最常用的断言。
我们将Assert方法按如下分组:a.同等(Equality)断言b.一致性(Identity)断言c.比较(Comparison)断言d.类型(Type)断言e.条件(Condition)测试f.工具(Utility)方法1.同等断言主要包括Assert.AreEqual()、Assert.AreNotEqual()和Assert.IsNaN() 前两个方法测试2个参数是否相等。
重载的方法支持普通的值类型。
Assert.AreEqual(int expected, int actual );Assert.AreEqual(int expected, int actual, string message );Assert.AreEqual(int expected, int actual, string message,params object[] parms );Assert.AreEqual(uint expected, uint actual );Assert.AreEqual(uint expected, uint actual, string message );Assert.AreEqual(uint expected, uint actual, string message,params object[] parms );Assert.AreEqual( decimal expected, decimal actual );Assert.AreEqual( decimal expected, decimal actual, string message );Assert.AreEqual( decimal expected, decimal actual, string message,params object[] parms );Assert.AreEqual( float expected, float actual, float tolerance );Assert.AreEqual( float expected, float actual, float tolerance,string message );Assert.AreEqual( float expected, float actual, float tolerance,string message, params object[] parms );Assert.AreEqual( double expected, double actual, double tolerance );Assert.AreEqual( double expected, double actual, double tolerance,string message );Assert.AreEqual( double expected, double actual, double tolerance,string message, params object[] parms );Assert.AreEqual( object expected, object actual );Assert.AreEqual( object expected, object actual, string message );Assert.AreEqual( object expected, object actual, string message,params object[] parms );Assert.AreNotEqual(int expected, int actual );Assert.AreNotEqual(int expected, int actual, string message );Assert.AreNotEqual(int expected, int actual, string message,params object[] parms );Assert.AreNotEqual(uint expected, uint actual );Assert.AreNotEqual(uint expected, uint actual, string message );Assert.AreNotEqual(uint expected, uint actual, string message,params object[] parms );Assert.AreNotEqual( decimal expected, decimal actual );Assert.AreNotEqual( decimal expected, decimal actual, string message );Assert.AreNotEqual( decimal expected, decimal actual, string message,params object[] parms );Assert.AreNotEqual( float expected, float actual );Assert.AreNotEqual( float expected, float actual, string message );Assert.AreNotEqual( float expected, float actual, string message,params object[] parms );Assert.AreNotEqual( double expected, double actual );Assert.AreNotEqual( double expected, double actual, string message );Assert.AreNotEqual( double expected, double actual, string message,params object[] parms );Assert.AreNotEqual( object expected, object actual );Assert.AreNotEqual( object expected, object actual, string message );Assert.AreNotEqual( object expected, object actual, string message,params object[] parms );不同类型的数值可以按期望的那样进行比较。
Nunit测试报告NUnit是一个用于测试.NET代码的单元测试框架,它提供了一种简单且灵活的方式来进行单元测试。
本文将介绍如何创建并使用NUnit测试报告。
步骤一:安装NUnit框架首先,我们需要安装NUnit框架。
可以通过NuGet包管理器来安装NUnit。
打开Visual Studio并选择你的项目,在解决方案资源管理器中右键单击项目,选择“管理NuGet程序包”。
在NuGet包管理器中搜索“NUnit”,然后安装最新版本的NUnit框架。
步骤二:创建测试类在项目中创建一个新的测试类,该类将用于定义测试方法。
测试类应该以“Test”结尾,以便与其他类进行区分。
以下是一个示例测试类的代码:using NUnit.Framework;[TestFixture]public class MyTests{[Test]public void TestAddition(){int result = Calculator.Add(2, 3);Assert.AreEqual(5, result);}}在上面的示例中,我们定义了一个名为“MyTests”的测试类,并在其中定义了一个名为“TestAddition”的测试方法。
在测试方法中,我们调用了一个名为“Calculator.Add”的方法来执行加法运算,并使用断言来验证结果是否符合预期。
步骤三:运行测试完成测试类的编写后,我们可以使用NUnit Test Runner来运行测试。
在Visual Studio中,选择“测试”菜单,然后选择“运行”>“所有测试”。
这将会运行项目中的所有测试方法,并生成测试报告。
步骤四:查看测试报告当测试完成后,我们可以查看生成的测试报告。
NUnit会生成一个包含测试结果的HTML文件。
打开该HTML文件,你将看到一个详细的测试报告,其中包含测试的结果、通过的测试用例、失败的测试用例以及其他有关测试的统计信息。
结论通过使用NUnit,我们可以轻松地进行单元测试,并生成详细的测试报告。
NUnit+NUnitAsp使用手册内容提纲:1、NUnit1.1、NUnit概述1.2、NUnit的使用1.2.1、安装1.2.2、测试实现1.2.3、图形化界面的使用(nunit-gui.exe)1.2.4、命令行界面的使用(nunit-console)2、NUnitAsp2.1、NUnitAsp 概述2.2、NUnitAsp的使用2.2.1、安装2.2.2、使用参考资料1、NUnit返回页首--------------------------------------------------------------------------------1.1、NUnit概述NUnit是一个用来专门针对.Net应用程序进行单元测试的工具,利用它我们可以很方便的编写一个单元测试代码,方便我们进行单元测试。
NUnit最新的版本是2.1版,大家可以到站点/ 去下载。
使用NUnit可以通过两种方式:1.图形化界面nunit-gui.exe2.命令行方式nunit-console.exe返回页首--------------------------------------------------------------------------------1.2、NUnit的使用返回页首--------------------------------------------------------------------------------1.2.1、安装NUnit默认是安装在C:\Program Files\Nunit V2.1,安装成功后会在桌面出现一个快捷方式。
我们可以通过运行安装包自带的例子(nunit.tests.dll.)来验证安装是否成功,下面就是安装成功后出现的界面:返回页首--------------------------------------------------------------------------------1.2.2、测试实现1.测试工程的建立a.新建一个.Net类库,添加对nunit.framework.dll的引用,给类加上一个“TestFixture”特性,表明这个类包含测试代码;b.对具体的测试方法添加一个“Test”特性,表明这是一个测试方法,并且测试方法的返回值必须为void并且不能带有参数c.添加对要测试代码(dll)的引用namespace bank{using NUnit.Framework;[TestFixture]public class AccountTest{[Test]public void TransferFunds(){}}}2.Assert类的作用Assert类用在测试方法中,它定义了一组方法用于检查给定的条件,Nunit 可以通过这个类提供的方法。
NUnit基本使⽤⽅法通常的单元测试框架都以他们⽀持的语⾔的开头字母加上Unit作为名字,他们统称为xUnit框架。
C++的叫做CppUnit,Java的叫做JUnit,.Net的叫做NUnit。
当然不是所有的都这么命名,但⼤部分如此。
下⾯我主要讲解⼀下NUni的⼀些基本操作。
1:Nunit两个重要属性1.1:[TestFixture]这个是标识包含⾃动化测试的类,可能改成TestClass⼤家更加理解。
但是代码是⽆法编译过去的。
1.2:[Test]这个是标识这个⽅法需要⾃动化测试的。
记得把这个属性加在要测试的⽅法上。
2:编写第⼀个单元测试2.1:⼀个单元测试通常包含三个⾏为:2.1.1:准备对象(就是对哪个对象就⾏操作)2.1.2:操作对象(对对象进⾏⼀些逻辑处理)2.1.3:断⾔(Assert)和预判产⽣的结果对⽐2.2:编写⼀个判断后缀名的⽅法public bool IsValidExtensions(string fileName){if (string.IsNullOrWhiteSpace(fileName)) throw new ArgumentNullException("fileName");var extension = Path.GetExtension(fileName);if (extension.Contains("pdf")){return true;}return false;}2.3:编写测试⽅法2.3.1:Assert这个类Assert.IsFalse(bool condition, string message)参数1:返回的结果参数2:展⽰失败的信息Assert.AreEqual(int expected, int actual, string message)参数1:期望的结果参数2:实际的结果参数3:展⽰失败的信息当然Assert很多⽅法可以⾃⼰去学习。
visual studio nunit使用方法
在Visual Studio中使用NUnit进行单元测试,需要以下步骤:
1.安装NUnit和NUnit测试框架。
2.创建测试项目。
3.编写测试用例。
4.运行测试。
5.安装NUnit和NUnit测试框架
在Visual Studio中,打开工具>扩展和更新>联机。
在搜索框中输入NUnit,然后单击查找。
找到NUnit和NUnit测试框架,然后单击安装。
创建测试项目
在Visual Studio中,打开文件>新建>项目。
在项目类型下,选择Visual C#>测试>单元测试项目。
在项目名称文本框中输入项目名称,然后单击确定。
编写测试用例
测试用例是用来验证代码是否符合预期行为的代码。
测试用例通常由以下部分组成:
1.测试名称:用于标识测试用例。
2.测试说明:用于描述测试用例的目的。
3.测试预期结果:用于描述测试用例的预期结果。
4.测试代码:用于验证代码是否符合预期行为的代码。
NUnit学习笔记⼆Mock有时候⼀些测试情况不可能真实、⽅便的模拟出来,这个时候可以借助Mock对象。
Mock对象也就是真实对象在调试期的替代品。
使⽤mock对象进⾏测试的时候,总共分三个步骤,分别是1、使⽤⼀个接⼝来描述这个对象2、为产品代码实现这个接⼝3、以测试为⽬的,在mock对象中实现这个接⼝。
因为测试代码只会通过接⼝来引⽤对象,所以它完全不知道他引⽤的究竟是真实的对象还是mock对象。
(单元测试之道⽤的是 DotNetMock ,⽤的是2.2版本的,但是我⽤的是 2.9的,看类库中好象有NUnit.Mock,等研究⼀下,毕竟是头⼀次接触这⽅⾯的内容,难度还是有滴)下午看了下⽰例代码,照着例⼦做了个简单的demo⼀般是继承Mock类,以下是DotNetMock的helpMockObject ClassBase Mock Object. All custom Mock Objects can extend this object.⼀般的程序结构是这样的//MyMockpublic class MyMock:Mock{//略代码//申明继承了IExpectation接⼝的类,⽐如ExpectationValueExpectation exp =new Expectation("name");//公开两个⽅法/属性可以设置//exp.Actual - 实际的值//exp.Expected -期望的值}//测试代码//在测试代码中,赋值,调⽤MyMock.Verity() ⽅法进⾏验证。
[Test]public void Test_Misspasswork(){MockLogger log =new MockLogger();AccessController acc =new AccessController(log,"Access Control");log.ExpectedName ="Access Control";Assert.IsFalse(acc.CanAccess("userid",null));Assert.IsFalse(acc.CanAccess("userid",""));//inherit Mock’s Methodlog.Verify();Console.Write("Access Success");}。
nunit 报告格式-回复NUnit报告格式这篇文章将会针对NUnit报告格式进行详细解析,提供一步一步的回答。
NUnit是一个广泛使用的单元测试框架,它提供了丰富的功能来帮助开发者进行单元测试。
NUnit报告是在运行测试后生成的文档,用于呈现测试结果和详细信息。
我们将会探索如何设置和解读这些报告。
第一步:安装和设置NUnit首先,我们需要在项目中安装NUnit框架。
可以通过NuGet包管理器或者手动安装NUnit框架包。
确保已经安装并配置了NUnit框架,然后开始进行单元测试。
第二步:编写单元测试在项目中编写单元测试方法,并使用NUnit提供的特性进行标记。
这些特性可以包括[TextFixture](表示一个测试类),[Test](表示一个测试方法),以及其他一些帮助我们配置和组织测试的特性。
确保单元测试方法具有良好的命名规范,并且能够清晰地表达被测试的功能和预期结果。
第三步:运行单元测试通过选择合适的运行选项(例如通过NUnit的可视化界面或命令行运行),开始运行单元测试。
NUnit将会执行你的测试方法,并记录测试结果和其他相关信息。
第四步:查看NUnit报告运行完成后,你将会看到一个生成的NUnit报告文件。
这个报告文件一般是XML格式的,可以使用任何可以显示XML的编辑器或浏览器进行查看。
打开报告文件后,你将会看到一系列的测试结果和附加信息。
这些信息包括测试是否通过、测试运行时间、执行环境,以及任何其他你可能在单元测试方法中记录的信息。
第五步:分析报告内容根据你的需要,分析报告内容以获取有关测试结果的详细信息。
你可以查看失败的测试用例并查找失败的原因,也可以查看通过的测试用例以确认预期结果的正确性。
除了测试结果,NUnit报告也提供了执行统计信息,比如运行时间、测试数量、通过的测试数量等。
这些统计信息可以帮助你评估你的单元测试的整体性能。
第六步:调试和修改根据报告中的结果和分析,你可能需要进行代码调试和修改。
单元测试之道(使用NUnit)2010-08-02 作者:张洋来源:EricZhang's Tech Blog首先来看下面几个场景你是否熟悉1、你正在开发一个系统,你不断地编码-编译-调试-编码-编译-调试……终于,你负责的功能模块从上到下全部完成且编译通过!你长出一口气,怀着激动而又忐忑的心情点击界面上的按钮,顿时你刚刚的轻松感烟消云散:系统无法正常工作,你想读的数据显示不出来,你想存的东西也送不到数据库……于是,你再次回到IDE里,设断点、调试、一层一层跟踪,当你精疲力尽终于将数据送到数据库里,你又发现了其它问题,于是你继续设断点、调试、编译、调试……2、你狂躁地敲击着键盘和鼠标,咒骂着不断出现的bug:啊?这里怎么没返回值啊!哎?这里不该是0啊!不对啊,这里怎么没数据……你永远不知道还有多少bug,你也永远不知道你的改动会不会引入其它bug——这里有几十个甚至上百个类,几百几千个方法!我不能都照顾到啊!你感觉bugs像敲击鼹鼠游戏中的鼹鼠:打下了这个,另一个又从其它洞口露出头来……3、也许是毕业答辩的演示,也许是客户的审查,你小心地打开自己要演示的系统,进行着预定的操作,忽然,有个功能不能正常运行,你大汗淋漓,在答辩老师或者客户质疑且不满的目光下你试了又试,但还是于事无补……于是,答辩老师可能扭头便走,客户可能愤然离去,然后离去的还有你的学位证和项目奖金。
当后来你检查代码时,发现这一切竟然只是因为一个底层工具类中一个方法输出结果为空。
如果你觉得上面的场景令你似曾相识甚至痛心疾首,那么你应该看完这篇文章。
什么是单元测试单元测试(Unit Test)的一个测试用例(Test Case)是一小段代码,这段代码用于测试一个小的程序功能(一般是一个方法或相关的几个方法)行为是否正常。
下面给出一个实际项目中单元测试用例的代码,大家可以不用深究这段代码中的细节,这里贴这段代码只是给大家一个直观的感觉。
NUnit详细使用方法前一段时间,有人问我在.NET里如何进行TDD 开发.这个问题促使我想对NUnit做一个详细的介绍.因为我们大家都知道NUnit是在.NET进行TDD的利器. 如果你已经知道很多关于NUnit的应用,请指出我的不对之处和提出一些建议,使本文更加完善.如果你对NUnit还不是很了解前一段时间,有人问我在.NET里如何进行TDD开发.这个问题促使我想对NUnit做一个详细的介绍.因为我们大家都知道NUnit是在.NET 进行TDD的利器.如果你已经知道很多关于NUnit的应用,请指出我的不对之处和提出一些建议,使本文更加完善.如果你对NUnit还不是很了解的话,我建议你还是阅读一下.本文分为以下部分:1. TDD的简介首先什么是TDD呢?Kent Beck在他的<<测试驱动开发>>(Addison-Wesley Professional,2003)一书中,使用下面2个原则来定义TDD:·除非你有一个失败的自动测试,永远不要写一单行代码.·阻止重复我想第一个原则是显而易见的.在没有失败的自动测试下就不要写代码.因为测试是嵌入在代码必须满足的需求中.如果没有需求,就没有必要实现任何东西.所以这个原则阻止我们去实现那些没有测试和在解决方案中不需要的功能.第二个原则说明了在一个程序中,不应该包含重复的代码.如果代码重复,我想这就是不好的软件设计的象征.随着时间的流逝,它会对程序造成不一致的问题,并且使代码变非常混乱,因为我们时常不会记得重复代码的位置.如果发现代码重复,我想我们应该立即删除代码重复.其实这就涉及到重构了.在这里我就不多讲了.一般来说,测试分为2种类型,一是程序员自己的测试,另外一种是客户的测试.关于客户测试,我推荐一个FIT的框架,非常不错。
在这里,我们讲的TDD就是程序员测试.那么什么是程序员测试呢?我认为就是我们常说的单元测试.既然是单元测试,在.NET里势必会用到某些工具,目前最著名恐怕就是我即将介绍的NUnit了。
2.NUnit的介绍NUnit是一个单元测试框架,专门针对于.NET来写的.其实在前面有JUnit(Java),CPPUnit(C++),他们都是xUnit的一员.最初,它是从JUnit而来.现在的版本是2.2.接下来我所用的都是基于这个版本.NUnit最初是由James W. Newkirk, Alexei A. Vorontsov 和Philip A. Craig, 后来开发团队逐渐庞大起来.在开发过程中, Kent Beck 和Erich Gamma2位牛人也提供了许多帮助.看来对于NUnit 还真是下了一番力气了.JNUnit是xUnit家族种的第4个主打产品,完全由C#语言来编写,并且编写时充分利用了许多.NET的特性,比如反射,客户属性等等.最重要的一点是它适合于所有.NET语言.如果你还没有下载,可以到/去下载.2.1 NUnit的介绍Ok,下面正式讲解NUnit.在讲解之前,看看几张图片:图1 NUnit运行的效果图2 NUnit运行的另外一个效果从中我们可以非常容易发现,右边是个状态条,图1是红色的,图2是绿色的.为什么会这样呢?因为如果所有测试案例运行成功,就为绿色,反之如果有一个不成功,则为红色,但也有黄色的.左面的工作域内则是我们写的每一个单元测试.通过上面的图片,我想你对NUnit有个总的了解了.下来还是分为2个部分,一是NUnit的布局,另外一部分就是它的核心概念.首先熟悉一下NUnit GUI的布局.让我们更进一步看一下测试运行器窗口的布局。
在右边面板的中间,可以看到测试进度条。
进度条的颜色反映了测试执行的状态:绿色描述目前所执行的测试都通过黄色意味某些测试忽略,但是这里没有失败红色表示有失败底部的状态条表示下面的状态:状态.说明了现在运行测试的状态。
当所有测试完成时,状态变为Completed.运行测试中,状态是Running: <testname> (<test-name>是正在运行的测试名称)。
Test Cases说明加载的程序集中测试案例的总个数。
这也是测试树里叶子节点的个数。
Tests Run 已经完成的测试个数。
Failures 到目前为止,所有测试中失败的个数.Time 显示运行测试时间(以秒计)File主菜单有以下内容:New Project允许你创建一个新工程。
工程是一个测试程序集的集合。
这种机制让你组织多个测试程序集,并把他们作为一个组对待。
Open 加载一个新的测试程序集,或一个以前保存的NUnit工程文件。
Close关闭现在加载的测试程序集或现在加载的NUnit工程。
Save 保存现在的Nunit工程到一个文件。
如果正工作单个程序集,本菜单项允许你创建一个新的NUnit工程,并把它保存在文件里。
Save As允许你将现有NUnit工程作为一个文件保存。
Reload 强制重载现有测试程序集或NUnit工程。
NUnit-Gui自动监测现加载的测试程序集的变化。
当程序集变化时,测试运行器重新加载测试程序集。
(当测试正运行时,现在加载的测试程序集不会重新加载。
在测试运行之间测试程序集仅可以重新加载。
一个忠告:如果测试程序集依赖另外一个程序集,测试运行器不会观察任何依赖的程序集。
对测试运行器来说,强制一个重载使全部依赖的程序集变化可见。
Recent Files 说明5个最近在NUnit中加载的测试程序集或NUnit工程(这个列表在Windows注册表,由每个用户维护,因此如果你共享你的PC,你仅看到你的测试)。
最近程序集的数量可以使用Options菜单项修改,可以访问Tool主菜单。
Exit退出。
View菜单有以下内容:Expand一层层扩展现在树中所选节点Collapse 折叠现在树中选择的节点Expand All递归扩展树中所选节点后的所有节点Collapse All递归折叠树中所选节点后的所有节点Expand Fixtures扩展树中所有代表测试fixture的节点。
Collapse Fixtures 折叠树中所有代表测试fixture的节点。
Properties 显示树中现所选节点的属性。
Tools 菜单由这些项:Save Results as XML作为一XML文件保存运行测试的结果。
Options让你定制NUnit的行为。
现在看看右边,你已经熟悉Run按钮和进度条。
这里还有一个紧跟Run按钮的Stop按钮:点击这个按钮会终止执行正运行的测试。
进度条下面是一个文本窗口,在它上方,由以下4个标签:Errors and Failures 窗口显示失败的测试。
在我们的例子里,这个窗口是空。
Tests Not Run 窗口显示没有得到执行的测试。
Console.Error 窗口显示运行测试产生的错误消息。
这些此消息是应用程序代码使用Console.Error输出流可以输出的。
Console.Out窗口显示运行测试打印到Console.Error输出流的文本消息。
2.2 一些常用属性接下来,我将讲述这个框架如何使用.同时也涉及到一些非常重要的概念,我想其客户属性是非常重要的.在NUnit里,有以下几种属性: Test FixtureTest下面我将对每种属性一一讲解.TestFixtureAttribute本属性标记一个类包含测试,当然setup和teardown方法可有可无.(关于setup 和teardown方法在后面介绍)做为一个测试的类,这个类还有一些限制必须是Public,否则NUnit看不到它的存在.它必须有一个缺省的构造函数,否则是NUnit不会构造它.构造函数应该没有任何副作用,因为NUnit在运行时经常会构造这个类多次,如果要是构造函数要什么副作用的话,那不是乱了.举个例子TestAttributeTest属性用来标记一个类(已经标记为TestFixture)的某个方法是可以测试的.为了和先前的版本向后兼容,头4个字符(“test”)忽略大小写.(参看/test.html) 这个测试方法可以定义为:从上面可以看出,这个方法没有任何参数,其实测试方法必须没有参数.如果我们定义方法不对的话,这个方法不会出现在测试方法列表中.也就是说在NUnit的界面左边的工作域内,看不到这个方法.还有一点就是这个方法不返回任何参数,并且必须为Public.例如:一般来说,有了上面两个属性,你可以做基本的事情了.另外,我们再对如何进行比较做一个描述。
在NUnit中,用Assert(断言)进行比较,Assert是一个类,它包括以下方法:AreEqual,AreSame,Equals,Fail,Ignore,IsFalse,IsNotNull,具体请参看NUnit的文档。
3.如何在.NET中应用NUnit我将举个例子,一步一步演示如何去使用NUnit.第1步.为测试代码创建一个Visual Studio工程。
在Microsoft Visual Studio .NET中,让我们开始创建一个新的工程。
选择Visual C#工程作为工程类型,Class Library作为模板。
将工程命名为NUnitQuickStart.图4-1是一个描述本步骤的Visual Studio .NET。
图4-1: 创建第一个NUnit工程第2步.增加一个NUnit框架引用在Microsoft Visual Studio .NET里创建这个例子时,你需要增加一个NUnit.framework.dll引用,如下:在Solution Explorer右击引用,然后选择增加引用NUnit.framework组件,在Add Reference对话框中按Select 和OK按钮。
图4-2 描述了这步:图4-2: 增加一个NUnit.framework.dll 引用到工程第3步.为工程加一个类.为工程加一个NumbersFixture类。
这里是这个例子的代码。
第4步.建立你的Visual Studio 工程,使用NUnit-Gui测试从程序->NUnit2.2打开NUnit-gui,加载本本工程编译的程序集.为了在Visual Studio .NET中自动运行NUnit-Gui,你需要建立NUnit-Gui作为你的启动程序:在Solution Explorer里右击你的NunitQuickStart工程。
在弹出菜单中选择属性。
在显示的对话框的左面,点击Configuration Properties夹选择出现在Configuration Properties夹下的Debugging。
在属性框右边的Start Action部分,选择下拉框的Program作为Debug Mode值。