测试驱动经验

来源:互联网 发布:数据分级管理模式 编辑:程序博客网 时间:2024/05/21 08:19

1。测试驱动-敏捷开发

  -测试:“你可以任意改我的代码,但是要保证我的测试都过”这是搞测试驱动开发的人经常说的话。
测试驱动的核心是,在开始写程序之前一定要写的是测试。也就是先写测试再写程序。最开始写测试,然后测试一定会失败,因为它调用了不存在的类--这个类会在后面实现。

    这样做的好处有2个:
    一个是写软件过程中目标明确。程序的功能就在测试里,让测试过了就可以check-in。这样可以集中自己的注意力来做一件事情,避免在写程序过程中出现思维混乱。但是这种习惯很难养成,而且开发速度会慢一点:)
    还有一个更重要的作用体现在软件的后期维护中。后期的软件非常庞大,经常出现的情况是,改了一个bug之后,会出现其他的bug,甚至会让以前出现修复好的bug重新出现。--但是,如果软件有相当数目的测试存在的话,这个问题会轻松很多。每改好一个bug,写一个测试。并且每次check-in时,都要让测试通过。

    有一个比喻我觉得很形象:如果软件是一个生命的话,测试就是他的骨骼。没有骨骼的生命难以维持。测试给程序指名了有且只有一个的出口。

    敏捷开发还有很多其他的要素,但是我觉得这个是最主要的,可以被应用于很多其他的领域。

2。测试的写法
    目前知道的:

    单元测试工具:CPPUnit。是测一个功能类的,如果这个类里面调用了其他的类中的方法,我们可以用mock,有mock4cpp。cppunit使用起来比较麻烦,但是在大型项目中,个人觉得是必不可少的。具体使用方法见google。

    集成测试工具:网页上有selenium test,js实现,测试一个页面是否有死链接的,非常好用。具体用法见selenium.thought.com。简单来说,是提交给测试系统一个html写的表格。表格的每一行代表一个命令,比如:click  id="submit"(代表点击id为submit的按钮)或者VerifyTextPresent  hello(代表断言页面上会出现hello的字样,如果没有出现,测试失败)。

    在小项目中,我们也许用不到cppunit。但是我们可以自己写测试代码来测我们的功能模块,用ASSERT()来让程序在进入不期望状态的的时候来通知我们。这样的好处是我们可以随时改动代码,而不担心它在什么时候会有bug出来。

3。重构的艺术
    “好的程序员会写出给人看的程序,而不好的程序员只能写出给机器看的程序(good programmer can write program readable for human while stupid programmer can only write program readable for mechine)”。来自refactor--the art of programming。

    我们要能够感知程序的“臭味”:
    设计的异味:
    僵化性(Rigidity):系统很难改变,因为每改动一处,就不得不改动其它地方。
    易碎性(Fragility):改变系统的某个部分,会破坏许多完全无关的部分。
    固化性(Immobility):很难将系统分解成可供其他系统重用的组件。

    不必要的重复性(Needless Repetition)
    类的管理原则:
    单一职能原则(The Single Responsibility Principle - SRP):一个类只能为一个原因而改变。类要有状态和一个行为。
    开放-封闭原则(The Open-Close Principle – OCP):软件实体(类、模块、方法等)应该允许扩展,不允许修改。而且父类不应该知道子类的情况,不应该为子类做准备。
里斯科夫替换原则(The Liskov Substitution Principle - LSP):子类型必须能够替代它们的父类型。
    依赖关系倒置原则(The Dependency Inversion Principle - DIP):上层模块应该不依赖于下层模块,它们都依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
    接口隔离原则(The Interface Segregation Principle – ISP):客户端不应该依赖于自己不用的方法。应分离接口,得到单一接口职能。
以功能来分类,从接口细化到具体类。而不应该先从具体类入手

    不要介意改动程序--因为我们有测试。哪怕一个命名错误,我们都应该改动它--因为这个名称有可能会让你在1个月之后抓狂。

4。由重构引出的。。。
    设计模式。四人帮的这本书是经典,看了这本书的感觉就像再生一样,才知道原来程序是这样写的。。。接口的艺术。


5。理想与现实
    以上的观点是从一个叫Rob什么什么的人的书中选出的。他是敏捷开发的创始人。当然,就像他所说的,如果真的把一个程序做得那么漂亮--比如说依赖接口之类的,一个程序会有很多很多的接口,必定会影响速度。这也就是一个矛盾--人能读懂的程序和计算机能读的程序之间的矛盾。我们应争取在这个地方找到一个平衡。

6。程序应该。。。
    瀑布模式
    总是有人把程序和做汽车来比较,公司是个装配工厂,每个人加工一部分。这样引出了瀑布开发模型。但是需求是不断改变的,瀑布开发模型的成功率不高。IBM在80年代开发的项目中,只有20%的项目是成功的。(数字很吓人,但是是我以前公司的老外和我说的,他叫Fred,在IBM工作过20年)。因为需求完全被挡住了,技术部成了公司的主导者,它决定市场部的人应该怎么和别人交涉。(the dog swails tails  , but now , tails swails dogs 狗摇尾巴编程了尾巴摇狗)。于是。。。。
    螺旋型模型
    采取大型迭代来满足客户需求,其实与瀑布模型每什么两样,只是让自己感觉舒服一些。
    CMM模型
    90年代初流行的。好像也差不多,流行称它是Cost More Money。因为他能保证产品的正确性,但是客户每改动一个需求,需要付钱。
    敏捷开发
    观点认为,做程序应该象生命在母体中的形成,不是先长头,再长脚,而是一起长。怎么能保证生命会长成自己想要的样子呢?----测试,骨骼的构成。它提倡2人一台电脑进行开发。一人写程序,另一个人检查语法错误或者思考逻辑。可以一人写测试,另一人写实现。

7。程序员应该。。。
    好的程序员不是象人们描述的那样,头发乱,不会说话,目光呆滞。好的程序员应该会思考。程序是一个机器,它可以让你减少重复工作。如果程序只会让人的生活更乱,那还不如退到一切,不要程序。

8。文档和UML图
    敏捷开发的观点我不是很提倡,但是从中可以学到不少东西。还有一个观点就是回归代码。Fred上一年在印度做的一个项目中,项目中有738个类,每个类起作用的逻辑执行语句不超过10行。有3000多个测试。在程序交付的前3天,Fred一个人改动了300多个类,他有胆量去改动他,但是他怕他的客户没胆量去听:)。
    另一个例子,我原来公司的程序,虽然不多,但也有300多个JUnit test 和300多个 selenium test。服务器check-in的权限是公开的,anyone can change anything。 但是有一点--要保证测试通过。谁把测试搞fail了,谁负责:)
    我想说的是,文档和UML图是给别人看的,测试才是真的,给自己用的。看一个程序的功能,首先看测试,测试说明的程序的目的。Rod建议UML图不要多画,因为他只会让人的思维更乱。最重要的画UML图的地方就是给客户交付的时候让客户看:)。他这样说是有道理的,UML图能很详细的反应代码内容---那为什么不直接看程序?:)

    敏捷开发思想个人觉得有点极端,但是如果把它和现在的开发结合一下也很有用。我只是个外行的小菜鸟,也没什么真正工作经验,以上是前几个月想到的几点东西,如有什么不妥之处,不要骂我:)

原创粉丝点击