单元测试关心的是:
   
    (1)单元外部需求的满足性。注重契约式编程中外部接口的前后契约条件检验,如前置契约不满足,外部接口应该返回失败,前置契约满足,则外部接口的输出、返回、对代码上下文语义环境的结果影响应该满足后置契约的要求。
   
    (2)单元内部实现应满足的设计语义假定(包括值域的、代码逻辑的),这些假定在编码时通过断言来表达(ASSERT),测试时可以直接作为检测手段。
   
    3.2 根据需求与设计方案设计用例
   
    设计用例时需要考虑的无非也是如下两点:
   
    (1)需求,这个是外部特性,在用例设计上必须以需求作为检查目标。这是首要的。
   
    (2)设计,这个是内部特性,在用例设计上应该对设计完备性(已经能直接指导编码)、以及设计的语义假设进行检查,如果设计不够完备,那么当然无从检验编码该达到什么目标,因为连蓝图都没有,无从校对起。语义假设是什么? 语义假设,是设计的内部逻辑特性。比如顺序内聚性是一种语义假设(在作A之前,必须先满足条件B,那么你需要在调用A时检测条件B是否满足)。语义假设检查主要通过ASSERT进行,下面会谈到。设计太粗则不够完备,无法针对设计方案进行细致的用例设计,必然导致测试得太粗。
   
    如果觉得用例写不下去,那么不要硬写,而是需要好好琢磨一下以上两点是否合理。在编码之前先写用例意味着:此时还没有“实现代码”,不存在实现的合理性问题,如果有不合理,则只会是需求或者设计上的不合理,测试驱动的一大好处也是能在开发的前期发现这两个起着决定性作用的研发环节的缺陷。
   
    3.3 自动化测试
   
    CUnit测试框架是一个比较好的自动化运行测试用例的手段。它可以用一个明显的方式规范化的向你表达:你的测试用例是都pass了,还是有的fail了。
   
    如果你的项目还没有集成CUnit测试框架了的VC版本,请尽快集成。
   
    必须做到能够自动化运行你的测试用例,不要干需要人工核对才能确认正确与否的傻事。
   
    每一次对代码进行了修改,都要运行已有的所有测试用例确保无误。
   
    3.4 将单元测试对实现代码的影响减低到少
   
    必须将单元测试对实现代码的影响减低到少,在实现代码中直接嵌入测试代码不是一个好的方法。好的情况是:测试代码、测试用例与实现代码完全分离,完全可拆分,在测试用例容易规范化的情况下尽量用规范化的表达方式(比如用xml格式的纯文本记录测试用例)。在这方面可以动很多脑筋,下面我主要提两点:。
   
    (1)打桩布局。进行单元测试必不可少的是对本单元引用的外部接口进行打桩。如果系统比较简单,所开发的模块与其他模块关联性不强,如果很容易提取出来自编译、自运行。那么按标准的单元测试打桩方法即可。
   
    如果系统比较复杂,所开发的模块与其他模块关联性很强,不容易脱离集成环境进行单元测试,可以参考我写的《集成系统中进行单元测试的静态打桩布局方式》一文,通过这种布局方法可以减少单元测试对实现代码的干扰。
   
    (2)活用ASSERT,ASSERT检查什么? 上面提到了,ASSERT检查的是设计上的语义假定。我们经常发现的“控制逻辑问题”是语义假定被违背了。ASSERT的触发意味着测试fail。ASSERT是位于实现代码之中的很好的测试手段。
   
    3.5 测试与开发同步进行
   
    测试工作与开发工作应该是并发进行。每次都只作一小步的工作,模块详细设计之后的开发工作是这样的:测试用例设计->编码->单元测试 的 迭代式增量开发。
   
    测试用例库的积累是聚沙成塔式的,不要编完1K甚至1W行代码再来测试,这么多行代码里藏着多少bug可能数都数不清,如果等到代码都已经写了这么多了才开始测试,设计测试用例、调试debug的困难与耗时良久是可想而知(这可能也是为什么大家觉得“单元测试困难”,不知道该怎么操作的主要原因)。应该一次多写100行编码,写这100行代码的测试用例,立刻验证这些代码能否通过测试,不行则必须马上解决,解决完了才进行下一轮迭代。当问题发生在刚刚编码的100行代码中时,要定位它是非常容易的。
   
    每一次新增代码,执行测试时,应该是执行目前积累下来的所有测试用例,这样可以判断,当前新增代码对既有代码逻辑是否有破坏性的影响。
   
    3.6 如何判断测试用例已经足够完备了
   
    用例设计覆盖程度应不仅达到必须的语句覆盖度,还需满足一定的分支覆盖度、路径覆盖度要求,我的经验是:应该达到任何一句代码判断逻辑“不小心写反了”(出现逻辑错误了)均能被用例自动测试出来。
   
    3.7 试点
   
    空谈无益,要体验一个新技术的好处,必须要亲身尝试。可以先找一些感兴趣的开发者来试验一下,一旦体会到测试驱动开发的好处,他们将会是这项技术好的宣传员与播种机。