使用NUnit在.Net编程中进行单元测试

简介: 原文地址:http://www.microsoft.com/china/community/Column/59.mspx 引言: 举一个可能会发生在你身边的事件将更能贴近实际,幸好我们现在就有一件在程序员看来非常普通的任务: 你今天第一天上班,你的项目经理拿给你一叠不算厚的文档,告诉你今天的任务是按照文档中的要求编写一个.Net类,可能因为任务并不复杂,所以他看上去非常的随意。
原文地址:http://www.microsoft.com/china/community/Column/59.mspx

引言:

举一个可能会发生在你身边的事件将更能贴近实际,幸好我们现在就有一件在程序员看来非常普通的任务:

你今天第一天上班,你的项目经理拿给你一叠不算厚的文档,告诉你今天的任务是按照文档中的要求编写一个.Net类,可能因为任务并不复杂,所以他看上去非常的随意。

今天能否很好的完成任务对你来说非常特殊,你拿过来后快速略过了前面大段的项目介绍,因为你知道那些对你并不重要,印象中好象是一个关于售票系统的工程。很快,你找了你需要关注的重点:类的需求说明文档。你详细的看了一遍,感觉并不复杂,类名Ticket,有一个只读的int型公共的属性,名称是Amount,还有两个方法,一个是名称是Sell,功能是将Amount减去一,表示卖掉了一张票,当然,票可不能为负数,如果是的话,抛出一个异常说明原因。另一个是Add,它有一个int型的参数,功能是将这个参数的值加到Amount中去,可能是表示进票之类的事情吧,你不太关心,反正这个程序很简单,你掩饰住内心的狂喜,打开电脑,调出编辑器,开始准备写程序了。

"喂,等等",项目经理不知道什么时候又转回来了,"我想知道你打算怎么进行单元测试,我最关心的是这个"。

"什么是单元测试?"你转过头一脸沮丧的看着失望的项目经理。

什么是单元测试:

在程序设计过程中会有许多种测试,单元只是其中的一种,单元测试并不能保证程序是完美无缺的,但是在所有的测试中,单元测试是第一个环节,也是最重要的一个环节。单元测试是一种由程序员自行测试的工作。简单点说,单元测试就是测试代码撰写者依据其所设想的方式执行是否产生了预期的结果。关于单元测试的重要性已经有许多文章做了很多深入的分析,这里就不再赘述。

NUnit是一个为Net准备的自动化单元测试框架,它的作用就是帮助你方便的完成单元测试工作,同鼎鼎有名的JUnit一样,都是xUnit家族的成员。它的下载地址是:http://www.nunit.org。

测试先行:

"什么?先写测试?"你一定非常惊讶,对!就是先来编写测试代码,按照极限编程(XP)的理论,写测试就是对软件进行设计的过程,它的重要性甚至超过了实际完成功能的代码。先将测试写完,然后再来完成代码,这样,所有的测试通过之日也就是程序完成之时。

首先,我们将NUnit提供的要nunit.framework.dll文件引入到工程中,并创建一个名为TicketTest的类:

[TestFixture]public class TicketTest{[Test]public void Add(){Ticket ticket = new Ticket();ticket.Add(100);Assertion.AssertEquals(100, ticket.Amount);}}

注意,其中的[TestFixture]和[Test]两个Attribute为NUnit所规定必须要添加的,这样,测试框架就可以知道哪些类或者方法需要进行测试。

我们在Add方法中定义了一个ticket对象,并给他加了100张票,然后就可以使用:

Assertion.AssertEquals(100, ticket.Amount);

来测试ticket的Amount属性是否确实为100。

接下来,我们再向TicketTest中添加一个测试Sell的方法:

[Test]public void Sell(){Ticket ticket = new Ticket();ticket.Add(100);ticket.Sell();ticket.Sell();ticket.Sell();Assertion.AssertEquals(97, ticket.Amount);}

这里,我们先加了100张票之后就一口气卖掉了3张,然后看看我们是否还剩下97张票。

好了,这两个方法的测试已经做完了,我们来看一下测试的结果,根据要求,我们写了如下代码:

public class Ticket{private int amount;public int Amount{get{return amount;}}public void Add(int num){}public void Sell(){}}

注意这段代码只是为了完成类的结构,方法的实现暂时先空着。然后将这段代码编译成一个dll动态连接库文件:UnitTest.dll。

我们运行NUnit的图形测试工具,打开我们编译好的dll文件,点"Run"按纽,就可以看到如下画面:

很醒目红色,表示测试并没有成功,不过这个是在我们的预料之中的。

接下来,我们向刚才的Ticket类中完成我们的Add方法实现代码:

public void Add(int num)

{

amount += num;

}

保存,重新编译。

切换到NUnit,再点Run,可以看到:

Add方法已经变成绿色了,再接着将Sell方法也完成:

public void Sell()

{

amount -= 1;

}

再来测试,结果就变成:

啊,总算变成美丽的绿色了,大家现在体会到环保的重要性了吧。:)

那么可以交任务了吗?等等,别急,还有个异常没测试呢,如果我们的Amount小于0的话,就会产生异常,那么,异常怎么测试呢?请接着看。

测试异常:

还是跟上面一样,先写出测试代码:

[Test][ExpectedException(typeof(Exception))]public void ExcpetionTesting(){Ticket ticket = new Ticket();ticket.Add(3);ticket.Sell();ticket.Sell();ticket.Sell();ticket.Sell();}

其中,[ExpectedException(typeof(Exception))]表示我们希望能捕获到发生的异常,如果没有捕获到异常,则表示测试失败。

后面的代码很好理解,我们加了三张票,却卖了四张出去,这可不是炒股,以后没办法平仓的。:)

编译运行,我们看到以下的测试画面:

在Ticket类中,我们修改一下Sell方法,让它变成:

public void Sell()

{

if(amount - 1 < 0)

throw new Exception("Amount不能为0");

amount -= 1;

}

编译,再测试,结果如下:

好了,到了这里就算完成我们的单元测试之旅了,大家对如何在C#中进行单元测试一定已经有了一个基本的认识。另外,NUnit并不是只针对C#,事实上,你可以在任何.Net语言中使用NUnit来测试你的单元,方法都一样。

总结:

单元测试看上去虽然有点麻烦,但是它为程序员提供了一个安全的观点,让程序员对自己的程序更加有信心,在减少开发后期进行频繁Debug所耗费时间的同时也为应用软件提供了第一道安全防护网,因此,单元测试是提高开发效率和软件品质的一个重要的手段。

利用UNint,我们可以在.Net编程过程中非常方便的进行单元测试,它图形化的界面和简单而强大的测试框架为我们提供了一个非常舒适而有趣的测试环境,能够让程序员觉得进行单元测试并不枯燥乏味,习惯后甚至还能成为一种乐趣。

看完本文,如果你是引言中那个可怜的程序员的话,你现在就一定能轻松的面对你的项目经理,交上一份令人放心的代码答卷。

目录
相关文章
|
18天前
|
测试技术 持续交付 API
深入挖掘探索.NET单元测试
【10月更文挑战第11天】
34 2
|
14天前
|
测试技术 C# 数据库
C# 单元测试框架 NUnit 一分钟浅谈
【10月更文挑战第17天】单元测试是软件开发中重要的质量保证手段,NUnit 是一个广泛使用的 .NET 单元测试框架。本文从基础到进阶介绍了 NUnit 的使用方法,包括安装、基本用法、参数化测试、异步测试等,并探讨了常见问题和易错点,旨在帮助开发者有效利用单元测试提高代码质量和开发效率。
116 64
|
19天前
|
传感器 数据采集 物联网
探索.NET nanoFramework:为嵌入式设备编程的新途径
探索.NET nanoFramework:为嵌入式设备编程的新途
34 7
|
19天前
|
测试技术 API 开发者
精通.NET单元测试:MSTest、xUnit、NUnit全面解析
【10月更文挑战第15天】本文介绍了.NET生态系统中最流行的三种单元测试框架:MSTest、xUnit和NUnit。通过示例代码展示了每种框架的基本用法和特点,帮助开发者根据项目需求和个人偏好选择合适的测试工具。
30 3
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
43 2
|
1月前
|
安全 网络安全 数据安全/隐私保护
Python渗透测试之流量分析:流量嗅探工具编程
Python渗透测试之流量分析:流量嗅探工具编程
|
3月前
|
Java Spring 自然语言处理
Spring 框架里竟藏着神秘魔法?国际化与本地化的奇妙之旅等你来揭开谜底!
【8月更文挑战第31天】在软件开发中,国际化(I18N)与本地化(L10N)对于满足不同地区用户需求至关重要。Spring框架提供了强大支持,利用资源文件和`MessageSource`实现多语言文本管理。通过配置日期格式和货币符号,进一步完善本地化功能。合理应用这些特性,可显著提升应用的多地区适应性和用户体验。
40 0
|
3月前
|
Java Spring UED
Spring框架的异常处理秘籍:打造不败之身的应用!
【8月更文挑战第31天】在软件开发中,异常处理对应用的稳定性和健壮性至关重要。Spring框架提供了一套完善的异常处理机制,包括使用`@ExceptionHandler`注解和配置`@ControllerAdvice`。本文将详细介绍这两种方式,并通过示例代码展示其具体应用。`@ExceptionHandler`可用于控制器类中的方法,处理特定异常;而`@ControllerAdvice`则允许定义全局异常处理器,捕获多个控制器中的异常。
48 0
|
3月前
|
API 开发者 Java
API 版本控制不再难!Spring 框架带你玩转多样化的版本管理策略,轻松应对升级挑战!
【8月更文挑战第31天】在开发RESTful服务时,为解决向后兼容性问题,常需进行API版本控制。本文以Spring框架为例,探讨四种版本控制策略:URL版本控制、请求头版本控制、查询参数版本控制及媒体类型版本控制,并提供示例代码。此外,还介绍了通过自定义注解与过滤器实现更灵活的版本控制方案,帮助开发者根据项目需求选择最适合的方法,确保API演化的管理和客户端使用的稳定与兼容。
157 0
|
4天前
|
测试技术 开发者 UED
探索软件测试的深度:从单元测试到自动化测试
【10月更文挑战第30天】在软件开发的世界中,测试是确保产品质量和用户满意度的关键步骤。本文将深入探讨软件测试的不同层次,从基本的单元测试到复杂的自动化测试,揭示它们如何共同构建一个坚实的质量保证体系。我们将通过实际代码示例,展示如何在开发过程中实施有效的测试策略,以确保软件的稳定性和可靠性。无论你是新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。