前言:最近正在研究一个新项目的开发工作,这个项目的要求是必须写UnitTest,对于我个人来讲是很不喜欢写UnitTest的感觉这个东西会很大程度的延误开发进度,所以之前项目的UnitTest是能不写就不写,好在作坊式的开发不在乎你写不写,功能Work就OK了,好多技术大拿都对UnitTest情有独钟,可能对于我这种码农来说无法理解其好处吧,小小抱怨也无力改变什么,只能研究研究UnitTest了。

  当我在VS12中想通过右键找到Create UnitTest这个选项的时候,我发现10中给写UnitTest带来极大方便的选项在12 13中竟然没有了(也可见我多久没写UnitTest了lol),为什么微软要将这个功能取消了呢,我个人认为是为了更好的满足TDD的开发模式,微软对于TDD的开发模式可以说是大力的支持,甚至用VS 2012的开发团队为模板来向我们这些屌丝程序员来展示什么是优雅的C#开发。那何为TDD呢,下面切入正题来说说我的一点理解。

  TDD(测试驱动开发) 是测试先行的方式,也就是说根据需求写驱动(写测试用例)。通过用例从红灯变成绿灯,使其通过了把实现的代码生成出来。通常我们的开发模式是先写完Code,然后Create UnitTest,此种方式属于测试后行。对于此两种方式,我个人感觉不能说就一定要TDD而完全否定测试后行的方式,但是TDD给我们带来的方便是今天想要谈的主题,对于两种方式的讨论,欢迎大家来辩。

  TDD此种方式最有意义的地方在于:不会因为你先去想代码实现而产生过度设计的问题,如果从实际的需求出发,你写出来的代码是最简单,最直接满足需求的方式,就不会产生过度设计的问题。在这里我同样想到了一种编程方式:结对编程,结对编程是一种将知识传播下去的方式,意思是熟悉此处逻辑的老人可以和新人一起来编写一块逻辑,通过去修改BUG,写代码,老人带着新人将这块一起做下来,包括新成员进来的时候可以通过此种方式将知识传播下去。这也是一种Code Review,两个人一起看,总比一个人看发现问题的机会要多一些,因为两个人的思路是不同的,总是一个人开发是有问题的。因此此处是想将结对编程和TDD结合的方式。一个人写Test Case,另一个人通过Test Case来写实现。下面就通过实际的例子来演示一下(演示的代码没有实际意义,只是想通过例子来展示结对编程和TDD结合)。

  比如说我们现在有一个需求求一个圆的周长,那我们需要设计两种用例,1、输入一个整数值,通过计算返回周长。2、输入一个负值,抛错。下面我需要两个人来结对通过TDD方式来实现这个Story,为了方便理解,我用大话设计模式的人物命名方式来指定两个开发人员,老鸟,菜鸟。

老鸟:我写一个类Circle,写好它的构造函数。

        private int _r;
/// <summary>
/// TODO: Complete member initialization
/// </summary>
/// <param name="p">radius</param>
public Circle(int r)
{
this._r = r;
}

然后我开始写UnitTest,先创建一个UnitTest工程,然后写Test Case,写好后生成Caculate方法,设置断言,想得到正确结果。

        [TestMethod]
public void TestPerimeter_FirstCase()
{
Circle worker = new Circle();
double result = worker.Caculate();
Assert.AreEqual(result, 6.28);
}

此时,我Run Test,结果是通不过,因为我的Caculate方法还没有实现,小鸟,那你来实现这个方法。

小鸟:so easy,分分钟搞定。

        private int _r;
private readonly double _pi = 3.14 * ; /// <summary>
/// TODO: Complete member initialization
/// </summary>
/// <param name="p">radius</param>
public Circle(int r)
{
this._r = r;
} public double Caculate()
{
return _r * _pi;
}

老鸟:OK,现在我们再Run Test,果然我们这个Case通过了。那我再写一个Test Case。

         [TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void TestPerimeter_SecCase()
{
Circle worker = new Circle(-);
double result = worker.Caculate();
}

再Run Test,又失败了。

小鸟:哦,因为没有对参数进行判断,没有考虑小于零的情况,我修改下Caculate方法的实现。

        public double Caculate()
{
if (_r < )
{
throw new ArgumentException();
}
return _r * _pi;
}

这样两种Case就全通过了。

这个小例子就算结束了,可以看出来,我们通过TDD的方式,根据Test Case来设计代码逻辑,可以使我们的逻辑没有任何过度设计,而且这样的方式使UnitTest的代码覆盖率很高。

最新文章

  1. Salesforce学习笔记(一)
  2. 记一次由于Java泛型类型擦除而导致的问题,及解决办法
  3. AADC安装指南
  4. APNS 服务推送通知
  5. IOS 公共类-MyMBProgressUtil Progress显示
  6. 【iOS】彩色TabBar切换动画实现
  7. 利用RxJava获取手机已安装的App的图片、应用名称和版本号
  8. HDOJ 1083 Courses
  9. Freemarker中通过request获得contextPath
  10. LeetCode Search a 2D Matrix(二分查找)
  11. 洛谷P1198 [JSOI2008]最大数
  12. C++ 必知必会:条款16 指向成员函数的指针并非指针
  13. jq实现地址级联效果
  14. 阿里巴巴2013年实习生笔试题A
  15. 利用PHP生成二维码(转)
  16. java定义和实现接口
  17. ubuntu 开发板ping通虚拟机挂载nfs服务器
  18. ORM “杀器”之 JOOQ
  19. TCP/IP学习笔记:TCP传输控制协议(一)
  20. 自定义支持多行显示的RadioGroup

热门文章

  1. poj 2079 Triangle(旋转卡壳)
  2. A*寻路算法的探寻与改良(三)
  3. phpDesigner 工具快捷键巧用
  4. PHP中使用函数array_merge()合并数组
  5. hdoj 2147 kiki&#39;s game【博弈】
  6. NoSQL数据库的四大分类表格分析
  7. php 燕十八 观察者模式代码例子
  8. 【JAVA - SSM】之MyBatis输出映射
  9. 使用泛型简单封装NGUI的ScrollView实现滑动列表
  10. 【转】Android Camera(五)使用Camera功能 AREA的理解