TDD测试驱动开发︱一个完整的TDD测试驱动开发演练案例
2022-11-06
来源:逸言 我是张逸
说明:本讲义是我在ThoughtWorks作为咨询师时,为客户开展TDD Code Kata而编写。案例为Guess Number,案例需求来自当时的同事王瑜珩。当时,我们共同在ThoughtWorks的Zynx交付团队,为培养团队TDD能力进行训练时,引入了本案例。讲义中给出的代码问题则来自客户方的受训学员,可谓“真实的代码坏味道”。个人认为TDD不只是开发方法,还应该是设计方法,因此讲义中包含了诸多设计原理、思想和原则。
目标收益
熟悉IDE快捷键;
掌握TDD基本知识;
识别代码坏味道,熟练运用重构手法;
熟悉JUnit与Mockito框架;
了解Google Guice框架;
整体需求
实现猜数字的游戏。游戏有四个格子,每个格子有一个0到9的数字,任意两个格子的数字都不一样。你有6次猜测的机会,如果猜对则获胜,否则失败。每次猜测时需依序输入4个数字,程序会根据猜测的情况给出xAxB的反馈,A前面的数字代表位置和数字都对的个数,B前面的数字代表数字对但是位置不对的个数。
例如:答案是1 2 3 4, 那么对于不同的输入,有如下的输出:
答案在游戏开始时随机生成。输入只有6次机会,在每次猜测时,程序应给出当前猜测的结果,以及之前所有猜测的数字和结果以供玩家参考。输入界面为控制台(Console),以避免太多与问题无关的界面代码。输入时,用空格分隔数字。
任务分解
TDD的一个重要步骤是在分析需求之后,对其进行任务分解。每个任务相当于一个功能点,它们都是可以验证的。在进行TDD时,可以根据具体情况,对任务再进行分解,或者增加一些我们之前未曾发现的任务。
练习:分解任务
我们对Guess Number分解的任务为:
随机生成答案
判断每次猜测的结果
检查输入是否合法
记录并显示历史猜测数据
判断游戏结果。判断猜测次数,如果满6次但是未猜对则判负;如果在6次内猜测的4个数字值与位置都正确,则判胜
讨论:选择开始的任务
在分解好任务开始测试驱动开发时,我们应该优先选择哪一个任务? 选择的标准包括:
任务的依赖性
任务的重要性
从依赖的角度看,并不一定需要优先选择前序任务,因为我们可以使用Mock的方式驱动出当前任务需要依赖的接口,而不用考虑实现。例如,“随机生成答案”任务与“判断每次猜测的结果”任务之间存在前后序的依赖关系,但实现的顺序却并不需要按照此顺序。
对于任务的重要性,主要是判断任务是否整个系统(模块)的核心功能。一个判断标准是确定任务是功能的主要流程还是异常流程。例如任务“检查输入是否合法”即为异常流程,可以考虑后做。
测试驱动开发
开始第一个任务
我们认为,任务“判断每次的猜测结果”可以作为起始的核心任务。
任务:判断每次的猜测结果
在进行测试驱动时,选择好任务后,就需要对测试用例进行分析。可以假设该任务就是你要实现的一个完整功能,然后从外部调用的角度去思考用例。这体现为两个方面:
选择测试样本;
驱动承担该职责的对象,根据意图设计接口;
选择测试样本的方法请参考实例化需求。例如,这里可以选择全中或全错等样本。通常情况下,编写的第一个测试应该选择最简单的样本。
知识:Specification By Example
由Gojko Adzic的著作Specification By Example(实例化需求),介绍了如
免责声明:
1、IT项目管理界发布的所有资讯与文章是出于为业界传递更多信息之目的,并不意味着赞同其观点或证实其描述。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请浏览者仅作参考,并请自行核实相关内容。
2、本站部分内容转载于其他网站和媒体,版权归原作者或原发布媒体所有。如文章涉及版权等问题,请联系本站,我们将在两个工作日内进行删除或修改处理。敬请谅解!