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

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

  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学习笔记16(错误、异常)

    一.什么是错误,什么是异常 错误是指在执行代码过程中发生的事件,它中断或干扰代码的正常流程并创建异常对象.当错误中断流程时,该程序将尝试寻找异常处理程序(一段告诉程序如何对错误做出响应的代码),以帮助 ...

  2. iOS基本网络请求

    常见的网络请求有同步GET, 同步POST, 异步GET, 异步POST. GET请求和POST请求的区别: 1. GET请求的接口会包含参数部分,参数会作为网址的一部分,服务器地址与参数之间通过 ? ...

  3. 深入浅出百度地图API开发系列(3):模块化设计

    在前面两张简单介绍了百度地图API的基础知识和使用之后,我们来分析一下百度地图API的基本架构,了解一下基本架构可以帮助我们更清晰的了解API的功能和调用过程,也就可以帮助我们在实际开发中可以更方便的 ...

  4. Matlab求极限

    matlab求极限(可用来验证度量函数或者隶属度函数)可用来验证是否收敛,取值范围等等. 一.问题来源 搜集聚类资料时,又看到了隶属度函数,没错,就是下面这个,期间作者提到m趋于2是,结果趋于1,我想 ...

  5. [转载]jquery tmpl使用方法

    动态请求数据来更新页面是现在非常常用的方法,比如博客评论的分页动态加载,微博的滚动加载和定时请求加载等. 这些情况下,动态请求返回的数据一般不是已拼好的 HTML 就是 JSON 或 XML,总之不在 ...

  6. Samza的ApplicationMaster

    当Samza ApplicationMaster启动时,它做以下的事情: 通过STREAMING_CONFIG环境变量从YARN获取配置信息(configuration) 在随机端口上 启动一个JMX ...

  7. Android 环境搭建 版本问题

    jdk1.6 1.7  eclipse 3.7.2    SDK-r12 ADT 12 SDK和ADT必须配套 搭建环境需要四个软件: 1.JDK(这是最新版本jdk1.7官方下载地址:http:// ...

  8. UIViewController中各方法调用顺序及功能详解

    UIViewController中各方法调用顺序及功能详解 UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, ...

  9. redis面试

    1. 使用Redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,li ...

  10. P163、面试题29:数组中出现次数超过一半的数字

    题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 思 ...