对已有系统如何开展TDD

前言

最近接手一个已经上线运行的产品,并负责后期的开发和维护。想着正好用这个过程尝试如何对已有产品进行TDD工程实践的可行性。今天就分享一下在这个过程中的感受和思考。
Kent Beck在他的经典《测试驱动开发》一书中提过,为已经能够工作的代码编写测试将是很难的一件事情,因为:

  1. 你的代码不是按照可测的标准进行编写。很难编写测试。
  2. 没有测试的反馈,后续改动、重构无法第一时间让你知道,例如哪些地方曾经好用而现在出现了问题。
  3. 如果你要先写测试,再修改功能代码,将会持续很久。因为你会遇到上面1和2的困境。他们是一个死循环。

Kent给的建议是对于已经work的代码暂时不要去动它,获得反馈也并不是只能通过测试代码。也可以从同事那里通过结对编程来获得。总之先考虑如何打破上面的死循环。开启一小步才是重点。

现状

我最近接手的产品是一个基于RESTFull的API服务,给其他产品提供需要的数据和操作。当然不出意外,系统没有function level的Unit Test。但是好的是有少量的基于Postman的Http Request脚本。也有开发人员为了开发功能编写的调用API的小程序。每次产品Release的实际测试,都是QA用一个使用当前API最多的另一个业务线产品做回归测试,从而知道最近的改动是否一切正常和达到预期。

Todo List

对方是3个开发人员的团队,我只有一个人。现实情况就是:1个月的交接期之后,我既要保证当前产品的稳定,又要保证后续开发和改动的进度。于是我给自己如下几个问题来思考下一步的行动方案:

  • 如何快速熟悉并掌握系统?
    传统的方式无外乎:看文档;看代码;跟代码。如果没有文档,代码注释不够,那一般只能最后一步运行程序设定断点,跟代码了。如果代码量还不少,从何下手也是一个问题,时间有限,总不能漫无目的的跟踪吧?基于这些考虑,我打算基于仅有的几次和开发人员的交接的会议中整理出系统的主要业务逻辑范围。基于这些业务逻辑形成验证目标场景,也就是对于系统确定的输入可以有明确的期待输出。我可以将主要业务逻辑在系统集成这个层面编写测试代码。注意:这里不是Function level,而是System level。但是目的是通过这些验证作为抓手成为跟踪代码的入口点。
    因为需要有一些断言来验证实际反馈和预期结果是否一致性。所以我仍然借助于单元测试框架,这里我使用的是xunit。

  • 如何保证添加新功能/修改功能后系统依旧稳定?
    当我按照上面的过程将主要的业务逻辑部分都写上至少一条验证Case之后。基于学习代码的经验,我会有更多逻辑的认识。这会驱动我将这些新发现的逻辑也用测试的形式固化下来。循环往复这个过程。你会不知不觉的发现已经有几十个case。这就是一张最基本的系统“安全网”。
    虽然这是系统集成测试,运行速度无法和Function level的单元测试相提并论,但是对于已存在的系统我们可以用这张网作为反馈系统。而新开发的功能就可以尝试Function level了。毕竟从0到1已经迈出一步了。

  • 如何保证系统依赖方发生修改后系统依旧稳定?
    只要是一个产品,无论怎样都无法避免和第三方系统集成,小到一个SDK API,大到另一个系统的API Service。我们常规的做法一般是:看API文档;编写小程序学习API。不过在看了《测试驱动开发》一书中提到的“学习测试(Learning Test)”这个模式之后,我眼前一亮。在编写小程序学习API的过程不也可以是编写TDD的过程吗?基于单元测试框架的断言,我们学习API可以明确的设定预期输入和期待输出。对于我们希望使用API的每一个使用场景都可以通过一个单元测试来实现。这样做除了学习API我们也留下来一套当前系统针对这个API使用场景的使用“安全网”。无论后续API版本升级还是有API调整,这一套安全网都能快速的反馈给我们是否对系统有影响。我还记得若干年前痛苦的对SharePoint SDK每个版本的改动做对比和评估,是多么的痛苦和无奈。居然被这么一个简单的办法解决了。

小贴士

上面这些做法是宏观的做法,落实到具体编程工具会有不同的实现方式。我使用donet core进行开发,下面介绍的一些小技巧会用他为例子:

  1. 就算是集成测试,为了运行速度和减少系统间调用复杂性,尽量使用内存模拟技术。
    • WebApplication可以使用Asp.Net 自带的TestServer。一个内存模拟web服务的轻量服务。无需真的host并监听一个web端口。
    • TestSever提供方法可以在系统关键位置注入服务,替换已有功能,方便测试场景的构建和使用。例如:认证服务的替换。数据库服务的替换(构建测试用例需要的特定数据库)。
  2. 对于一些复杂的第三方服务,可以通过测试替身(Test Doubles)进行替换,构建对应测试需要的服务返回内容。例如:Mountebank ;Postman Mock server等。
  3. 回调方法如何测试。我这个系统存在一个请求上运行调用异步回调的场景。也就是当Client发送请求之后系统马上返回请求已接收的消息,但是实际工作在另一个线程,当结束后会调用Client的API将结果返回。这种场景如果简单验证当前系统接收到请求并不是重点, 主要的是回调部分内容才是真正的业务逻辑验证的关键。结合上面的结合上面#1的TestServer,用依赖注入框架替换回调服务的内存实现版本,之后结合内存队列或者内存数据库来实现对回调方法传递数据的验证。

总结

测试驱动开发思想希望我们能为系统功能构建安全网。能够更有底气的应对系统重构。能够让开发的功能更准确的服务于需求。今天分享的对已有系统补充测试的过程主要是成本相对较高的集成测试级别,而并不是单元测试,但是能够达成目的的测试就是好测试。针对已有系统和新开发系统,我们要灵活应对。希望今天的分享对大家有帮助。

践行敏捷实践,让工作变得更美好。欢迎留言,交流落地经验。

参考引用

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容