现在接着上次说到的内容,如何在项目中进行单元测试。由于做了一些调整,我上次发的内容,我这次也会重新发一次,请认真看看。

一、软件开发过程中存在的问题(没有使用单元测试的情况下)

  1. 难于定位bug的位置
  2. 修改一个bug,容易引进n个bug
  3. bug越后期发现,修改越困难
  4. 后期系统的复杂性,导致难于修改和重构代码
  5. 开发人员常认为编译通过,进行了几次手工测试就等于测试通过
  6. 在完全依赖外部系统的情况下,无法进行有效的测试
  7. 手工测试效率地下,针对性不强
  8. 代码难以维护和复用
  9. 开发人员觉得测试和修改是额外的工作,认为代码通过编译和调试就完成任务

二、单元测试在开发过程中起到的作用

  1. 单元测试大大节约了测试和修改的时间
  2. 单元测试能快速定位bug
  3. 单元测试能使开发人员重新审视需求和功能的设计
  4. 单元测试强迫开发者以调用者而不是实现者的角度来设计代码,利于代码之间的解耦
  5. 自动化的单元测试能保证回归测试的有效执行
  6. 有效且便于测试各种情况
  7. 使代码可以放心修改和重构
  8. 单元测试可用作被测代码的用法说明,可作为开发文档使用
  9. 测试用例永久保存,支持随时测试

以下举一个本人项目的例子,这个被测方法是验证登陆用户是否为管理员或版主

例子:public bool IsAdminOrBoardMaster(IOnLineUser  p_OnLineUser)
{
if (!IsRegularUser(p_OnLineUser))//判断是否为有效用户
return false;
if (p_OnLineUser.UserType == UserType.Teacher)//判断是否为教师
{
if (IsHeadmanForUser(p_OnLineUser.UserIdentity))//判断是否为教师组组长
return true;
else
return IsCourseClassBoardMasterForUser(p_OnLineUser.UserId);//判断是否为课程班带教老师
}
else if (p_OnLineUser.UserType == UserType.Student)//判断是否为班长
return p_OnLineUser.UserIdentity == ;//身份为1的话,用户为班长,返回true
else
return true;//管理员
}
从以上例子可有以下的测试用例
  1. 用户为无效用户,返回false
  2. 用户有效,类型为管理员,返回true
  3. 用户有效,类型为学生且为班长,返回true
  4. 用户有效,但为普通学生,返回false
  5. 用户有效,类型为教师且为组长,返回true
  6. 用户有效,类型为教师且为课程班带教老师,返回true
  7. 用户有效,但为普通教师,返回false

根据上面的测试用例,运行单元测试,NUnit运行如下图

测试用例全部通过,现在我修改一下生产代码,令运行失败,如下图

单元测试可以好清楚地显示哪个方法,哪个参数报错了,出错原因在右面。本人通过这两个例子为了显示一下单元测试在我们实际开发中的其中一个功能,快速定位bug。下面将开始讲解如何在实际项目中应用单元测试。

三、如何在实际项目中应用单元测试(.Net项目为例)

1、以NUnit为例,示范几个简单的例子
2、单元测试的核心技术
  • 桩对象,是对系统中现有外部依赖的一个替代品,可人为控制
  • 模拟对象,模仿外部依赖,属于一个伪对象,用于检验交互行为
  • 隔离框架

NUnit标签介绍
  1. [TestFixture],用于标识一个包含NUnit自动化测试的类
  2. [TestCase],用于标识测试方法为一个参数化测试
  3. [ExpectedException],用于标识被测试方法应该抛出异常
  4. [Test],用于标识一个需要被调用的自动化测试
  5. [SetUp],会在测试类中的每个测试运行之前执行
  6. [TearDown],会在测试类中的每个测试运行之后执行
  7. [TestFixtureSetUp],会在测试类中的所有测试运行之前执行
  8. [TestFixtureTearDown],会在测试类中的所有测试运行之后执行
Assert类,用于证明某个假设是否成立
  1. Assert.IsTure(),用于验证结果是否为true
  2. Assert.IsFalse(),用于验证结果是否为false
  3. Assert.AreEqual(),用于验证期望的对象是否与实际一样
  4. Assert.AreSame (),用于验证两个参数引用是否为同一个对象

解除外部依赖的技巧
  1. 抽取接口,以允许替换底层实现
  2. 在被测类中注入中注入伪对象的实现

注入伪对象的几种方法
  1. 构造函数注入
  2. 属性注入
  3. 方法参数(参数注入)
  4. 工厂类注入
  5. 局部工厂方法注入(不讲)
  6. 抽取和重写注入

属性注入、参数注入和构造函数注入基本一致,只是注入的位置不一样。属性注入通过注入桩对象,参数注入通过方法的参数注入桩对象,下面看看工厂类注入
上面的例子,讲的都是桩对象的注入,其实模拟对象的注入跟桩对象是一样的,关键是要弄清楚桩对象和模拟对象的区别
桩对象的目的是解除外部依赖,为被测方法传入一个可控制的对象,让测试可以进行
模拟对象的目的是测试方法是否向外界发送了信息,检验交互行为,所以单元测试检验的对象不再是被测方法,而是模拟对象
 
隔离框架,用于快速生成桩对象和模拟对象,减少开发人员的负担,常用的隔离框架有Rhion Mocks、Moq等等

(二)NUnit单元测试心得的更多相关文章

  1. (一)NUnit单元测试心得

    由于各种缘由,一本<.Net单元测试艺术>突然出现在了我的办公桌上,于是我的单元测试之路就此开始.通过一两个月不间断的学习,以及不断结合具体的项目做开发,再结合书上的知识对单元测试有了一些 ...

  2. NUnit单元测试资料汇总

    NUnit单元测试资料汇总 从安装到配置 首先到官网http://www.nunit.org/下载如下图的资料,安装NUnit-2.6.1.msi包. 然后挂在VS2010外部工具这个地方来使用,工具 ...

  3. Nunit单元测试入门学习随笔(一)

    Nunit单元测试 一.插件安装与项目关联 选择工具~扩展和更新 点击联机~搜索Nunit安装图内三个插件 新建单元测试项目 勾选项目引用 二.Nunit学习 1.了解单元测试 单元测试在我的理解是测 ...

  4. C# ~ NUnit单元测试

    单元测试 单元测试(Unit Test)的一个测试用例(Test Case)是一小段代码,用于测试一个小的程序功能的行为是否正常,保证开发的功能子项能正确完成并实现其基本功能.一个单元测试是用于判断某 ...

  5. NUnit单元测试

    单元测试对程序员来说是非常重要的一门技术,但是在实际编程中却往往被程序员所忽视.微软的VS开发工具为我们提供了强大的单元测试环境,在VS当中可以直接对类库项目进行测试,极大的方便了程序员的自我纠错能力 ...

  6. Visual Studio 单元测试之二---顺序单元测试

    原文:Visual Studio 单元测试之二---顺序单元测试 此文是上一篇博文:Visual Studio 单元测试之一---普通单元测试的后续篇章.如果读者对Visual Studio的单元测试 ...

  7. nunit单元测试详解

    在粗略看了代码后,下面就详细说明相应的测试标记(属性)的用法. [TestFixture(arguments)]属性标记类为测试类,若没有填写参数,则测试类必须含有无参构造函数,否则需要相应的有参构造 ...

  8. Spring Boot(十二)单元测试JUnit

    一.介绍 JUnit是一款优秀的开源Java单元测试框架,也是目前使用率最高最流行的测试框架,开发工具Eclipse和IDEA对JUnit都有很好的支持,JUnit主要用于白盒测试和回归测试. 白盒测 ...

  9. NUnit单元测试示例

    单元测试的用法 1.下载NUnit软件 安装后打开界面如图: 2.新建测试项目 添加类库项目并在NuGet管理包中添加NUnit 这里添加NuGet的NUnit包要注意保持版本和之前下载的NUnit软 ...

随机推荐

  1. python总字符串

    前面我们讲解了什么是字符串.字符串可以用''或者""括起来表示. 如果字符串本身包含'怎么办?比如我们要表示字符串 I'm OK ,这时,可以用" "括起来表示 ...

  2. Sql之表的连接总结

    1.交叉连接(就是将两张表的数据 交叉组合在一起) 有两张表 客户表:[Sales.Customers] 和订单表:[Sales.Orders]. 业务需求:实现 Customer中custid(客户 ...

  3. [转载]C#中各种计时器

    1.使用 Stopwatch 类 (System.Diagnostics.Stopwatch) Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.在典型的 S ...

  4. Hibernate-Validation的使用

    首先是要加入下面两个包 hibernate-validator-4.1.0.Final.jar validation-api-1.0.0.GA.jar 如果在验证不通过的时候进行了添加.更新或删除操作 ...

  5. dijkstra,bellman-ford,floyd分析比较

    http://www.cnblogs.com/mengxm-lincf/archive/2012/02/11/2346288.html 其实我一直存在疑惑是什么导致dijkstra不能处理负权图? 今 ...

  6. "Principles of Reactive Programming" 之 <Persistent Actor State>学习笔记

    这是<Pinciples of Reactive Programming>week6的最后一课. 为什么需要把actor的状态持久化? 如果actor没有状态,那么在任何实时,这个acto ...

  7. 如何将class文件打包成jar 这里提供两种方式!

    原地址:http://blog.163.com/09zzy@126/blog/static/711976652011101001530/ 如何将class文件打包成jar文件,这是一个很严肃的问题,当 ...

  8. uEditor独立图片上传

    项目中.上传图片,非常希望有一款比较兼容的查件. 网上找了一些,图片上传立刻显示的js代码,还有uploadify.都会碰到这样那样的不兼容和其它头疼的问题. 后来想,干脆就用php的上传类最干脆.但 ...

  9. linux中class_create和class_register说明

    http://blog.csdn.net/angle_birds/article/details/16802099 本文介绍linux中class_create和class_register的相关使用 ...

  10. 落叶枫桥LOGO

    LOGO