加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 程序设计 > 正文

TDD实践之实用主义

发布时间:2020-05-23 09:33:43 所属栏目:程序设计 来源:互联网
导读:打印 文章 我的书签 您没有收藏的内容 登录 或 注册 以永久保存书签。 该内容已经被标记书签! 标记书签错误,请重试! TDD实践之实用主义 作者 李光磊 发布于 2008年10月20日 领域 架构 设计, 过程 实践, 语言 开发 主题 敏捷 , 编程 , 敏捷技术 标签 测试

  • 打印

文章

我的书签
  • 您没有收藏的内容

登录 或 注册 以永久保存书签。

该内容已经被标记书签!

标记书签错误,请重试!

TDD实践之实用主义

作者 李光磊 发布于 2008年10月20日

领域
架构 & 设计,
过程 & 实践,820" class="f_taxonomy" href="javascript:void()" class="outlink" data="/link?url=http://www.infoq.com/cn/development" name="development" rel="nofollow" target="_blank">语言 & 开发
主题
敏捷,
编程,
敏捷技术
标签
测试驱动开发
分享 |

TDD的概念和实践依然在被怀疑和争议。然而,质疑者驻足不前,实践者却不再理会争论的口水,而是脚踏实地的实践,并获取高效回报。在这个过程中,我们发现TDD和敏捷倡导的理念,帮助我们解决了一个又一个的工程问题。

相关厂商内容

ActionScript 3基本原理:数值和数学

Pycon 2011 China12月3-4日上海

送给光棍节的促销,电子商务的背后—《架构师》11月刊免费下载!

ActionScript 3基本原理:软件包

Flash Builder 4.5高级版试用版免费高速下载

相关赞助商

阿里云100万重金招募开发者。

1. 为沟通选择语言

我们在一个海员管理系统的开发中遇到了问题,这个领域的专业术语我们很难翻译。即使勉强翻译出了,也感觉辞不达意,无论是初看上去,还是过一段时间再看都一头雾水。比如,我们写出了下面的测试用例:

public void test_should_return_NOT_pass_if_duty_higher_than_second_mate_or_second_engineer_and_education_level_is_secondary_and_guraduated_after_2002_02_01() {
   ……
}

但其中second mate/second engineer是什么意思呢? secondary的education level具体又是什么?

还有:

public void test_should_return_third_mate_course_for_jianxi_third_mate() {
  ……
}

jianxi_third_mate是什么? 等等。

当然,我们可以制定一个术语表,请专业人士先帮我们翻译好,然后在代码中遵循这个术语表。然而随着需求的增加,术语层出不穷,并且有特定中国特色的名词根本就没有对应的翻译,于是这个问题就一直困扰着我们。

而直到有一天,在一次重构中我们把上面的第一个测试用例重命名了一下,一切似乎突然间开朗了:

public void test_应该算未通过_if_职务高于二副二管轮_而_学历只是中专_并且_毕业时间晚于2002年2月1日() {
   ……
}

Team里的人纷纷围过来,看着这个跟需求描述里的验收条件几乎一模一样的测试用例名称,感受到一种前所未有的清澈。大家几乎在几秒钟之内就做出了选择:这种形式是可以接受的,而且表达能力更强,交流效果不错。

什么?使用中文作为函数名?这似乎只是那些被主流舆论鄙视的"汉语编程"研究者才搞的东西,我们一直就被教育离这些东西远点,甚至汉语拼音都不推荐使用,一个经常拿来做反面教材的例子就是数据库表的列名使用汉语拼音,这被看作不专业的表现。又或者,以后团队中加入外国开发者怎么办?

幸运的是,我们是软件工程师,不是计算机科学家。学术理论可以极端,而工程一定是某种折衷。定理由自然界精确遵守,而工程却是各种应力的人为平衡。

具体到这个案例,让我们正视现实:

  1. 团队成员并不善长本项目领域的专业英语。
  2. 任何翻译都会造成一定的信息损失,尤其在一些具有中国特色的领域,比如"中专"翻译为英语就很难像中文一样简洁直观。
  3. 在可预见的将来,不会有老外加入开发团队。

而选用中文却能够让我们更好的坚持以下原则:

  1. 代码除了完成功能, 另外一个重要的功能是交流。(我们选择了对团队来说最有效的交流方式)
  2. 用测试用例的名字来描述需求。(用中文描述更精确, 易于理解)

当然我们也会失去一些东西,比如对上面提到的"应该坚持使用英文"原则的放弃。在这里我们认为放弃这条原则的收益大于损失。一种损失就是失去了学习英文的机会,比如上面最后一个测试用例,用中文写出来就是:

public void test_见习三副应该参加三副的培训() {
   ……
}

或者有人会说:"见习"的英语是"intern",常用词啊。然而系统中还有另外一类角色,叫"实习三副"等,那才是"intern"。实习是实际动手,担当实际的职责;见习是只看不练,跟在后面观摩学习。见习的英文单词是"noviciate",并不为项目组所熟悉,而我们也不再关心它。

总之,在实践中应当权衡各种利弊,选择对你来说最有效的方式。

2. 用大量测试来驱动

在项目组中曾经发生过自以为完成了某个特性,后来却发现漏掉了某些验收条件,甚至是比较重要验收条件的事情。而这也是TDD经常被质疑的一点,就是如何保证测试的完备性。因为总是想一点写一点,不经过深入的思考,不可避免的会漏掉某些测试条件。

然而,TDD并不妨碍你深入思考,只是劝你在实现时步子不要太大,小步前进获得对问题的进一步认识以随时调整设计和实现。不过今天不争论TDD的哲学问题,我们只是关注用什么样的实践来消除对于TDD测试完备性的疑虑。

事实上,完全可以根据需求文档,验收条件,进行"深入思考",从一开始就写下所有能想到的单元测试用例,就跟测试人员在产品出来前就对着需求准备测试用例一样。

哦,等等,这还叫 TDD 吗? TDD 所强调的小步前进,随时应变哪里去了?为全面的测试用例所花费的大量努力岂不是有浪费的风险?

嗯,不错,TDD强调小步前进的原因就是要避免浪费。如果我们能找到一种方法,既能够提醒我们不要忘记需求,又让我们在需求变化时不致浪费太多,岂不是皆大欢喜?

想想,我们用什么来描述需求?是测试用例名称,而不是测试用例的函数体,而名称的书写几乎是没有成本的。从需求文档中把验收条件抠出来即可。如:

public void test_会被认为不服从调配_if_the_seaman_在当前职位上曾经旷工() {
        // TODO
    }

    public void test_会被认为不服从调配_if_the_seaman_在当前职位上曾经请过病假() {
        // TODO
    }

    public void test_会被认为不服从调配_if_the_seaman_在当前职位上曾经请过事假() {
        // TODO
    }

    public void test_会被认为不服从调配_if_the_seaman_在当前职位上曾经被遣返() {
        // TODO
    }

    public void test_不会被认为不服从调配_if_the_seaman_在当前职位上从未旷工_请病假_请事假_和遣返() {
        // TODO
    }

两分钟,我们就把这个用户故事的测试用例按照验收条件里说的全部描述出来了。函数体全部都是空的,因此所有的测试都是通过的,不会强迫你一次性把所有的测试都实现。

每次你流览或修改这段代码,空的函数体或里面的// TODO都会提醒你还有测试没有完成。即使你不在这个特性上工作了,切换过来的Pair也会从你遗留的测试用例名称中迅速的了解需要做什么。

这种方法是怎么解决问题的呢?

第一,还是让我们正视现实:如果需求描述不和代码放在一起,开发人员很少会在开发过程中去翻阅需求文档,甚至是特性编码结束后。这在成熟的开发团队中会有改善,但仍然不可避免。把需求描述以测试用例名称的方式放进代码,便会无时无刻不在提醒开发者,还有这个这个这个验收条件没满足。

第二,我们依然坚持了以下原则:

  1. 用测试用例的名字来描述需求。
  2. 小步前进,编写一个测试用例,实现一段产品代码,编写下一个测试用例,实现下一段产品代码。(因为所有的未完成测试都是通过的,不妨碍你运行测试,提交代码和持续集成)
  3. 当实现过程中发现事情并不是当初想的那样时,随时更改或删除之前写的测试用例,不会造成大的浪费。(因为只是函数名加空的函数体,成本很低)

在开始写下"所有"的测试用例名称并不意味着一劳永逸。中间当需求发生变化,我们需要对应的添加或删除一部分测试用例。在实现的过程中,发现某些条件不在验收范围内,或许是之前没考虑到,那么跟BA/QA确认后,需要添加到用例列表中。

(细心的读者可能发现,这里面存在着重复。就是以普通文本形式存在的验收条件和以测试用例名称存在的验收条件。或许应该有类似SVN2Wiki的工具,来消除这类重复)

当然,完备性还有其它的含义和检测条件,不是说你提前多写几个用例就是完备了。这里只是用一种成本最低的方式来解决问题。

3. 一个环境,多个断言

随着时间的推移,项目组发现测试运行的越来越慢。当然,这是一个普遍现象,也已经有很多方法来加速测试的运行速度。但很多需要新工具的支持,而项目组暂时没时间去切换工具。有没有其它更方便的做法?

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读