Test Driven Development

虽然敏捷开发这个词已经臭大街,但是我仍然坚信TDD是正确的开发方式。其核心原理很简单就是更快的feedback cycle,即便TDD不能让我们可以在写代码之前就想好要写什么,但是起码它可以让我们在写完两三行代码之后就运行到那几行代码并验证一下。这总好过上线的时候发现php error去回滚要强吧。

Behavior Driven Development

传统的TDD被人诟病的地方在于细粒度的unit测试。我现在写代码,很少去写unit test来保证类或者包级别的行为了,因为懒。相比一个类的职责边界不清楚,更要命的问题是在 rd <-> pm 之间缺少一个文档来保证其契约。所谓Behavior Driven Development(BDD)的意思就是我们要写测试去记录下来我们和产品经理达成的那些共识,也就是“Live” “Contextual” “Document”:

  • 文档:这个东西应该是产品经理可以读得懂的东西,而不是什么python脚本

  • 有上下文:总是在描述一个场景里的某一个侧面,而不是所有细节

  • 可验证:如果文档不可以做为测试被验证,那么文档什么时候写出来就是什么时候过期被抛弃

BDD + Micro Service

微服务是必然的趋势,因为一个组织总是倾向于生长。我们看到的现状就是想要真正做到有一份文档记录产品经理和研发之间的默契,并且让这份文档是可测试的,我们就需要集成多个Micro Service去做一个接近端到端的集成测试。这种测试对于获得开发效率来说至关重要,因为团队间沟通和返工的成本是非常高的。和Micro Service在其他层面带来很多技术挑战一样,Micro Service的盛行对于测试驱动开发来说也是全新的他挑战。因为要驾驭一个多服务集成的应用做集成测试,需要超越junit的更广博的知识和耐心。传统的BDD工具更多是在制造各种各样的语法糖让代码写得像文档一样,然而并没有什么卵用。这里就一个很大的工具gap,需要新一代的工具让BDD适应这个micro service的时代,比如 https://github.com/taowen/devenv

无论是何种方式实现,我们可以看到的是在Micro Service时代,在Polyglot时代,靠一个语言的一个进程内的测试是很难实现测试驱动开发的了。我们越来越倚重集成测试来获得开发者改进代码的信心,以及不断快速迭代的开发效率。

Slow Local Build

大量的集成测试带来的一个直接后果是需要非常长的本地build的时间才可以知道我的这次改动是不是破坏了之前的功能。如果之前是一个单体的java应用,可能整个验证用junit在进程内mock掉一些heavy的服务可以跑得飞快,但是在现在这种多语言微服务的架构下,就不得不把所有进程都启动起来,然后跨进程甚至分布式地来验证整个系统。模块级别的测试不是答案,大部分的micro service拆分都是不合理的。

所以,我们RD也需要云。

新技术带来的机会

一个理想的开发云应该可以分布式地执行开发者的local build,即便是上百个集成测试也可以在一分钟内全部跑完。我构想可以利用三项技术:

这个过程应该是这样的:

  1. rsync上传本地开发中的代码到测试服务器上

  2. 把整个应用在docker容器内启动

  3. 利用 CRIU 技术把docker容器状态打一个快照

  4. 运行一个全流程的冒烟测试验证本次部署是ok的

  5. 把 CRIU 打的快照批量的恢复出一堆docker容器(docker提供了一致的文件状态,CRIU提供了一致的进程执行中状态)

  6. 甚至可以批量地在一堆机器上分布式地恢复出一堆docker容器

  7. 这些docker容器跑一个集成测试并报告执行结果

  8. 全部执行完之后,开发者从测试服务器获得最终的测试报告

  9. 如果有测试fail,利用docker+CRIU开发者可以完全在本地恢复出远程的集成测试的执行时状态并本地重现错误

其实说白了就是 docker + CRIU 的革命性技术让我们第一次拥有了每个虚拟机只跑一个测试的能力。神码tear down不干净导致测试random fail,都不再是问题。这样的开发云目前还没有,但是我相信已经有人在造了~


taowen
4.1k 声望1.4k 粉丝

Go开发者们请加入我们,滴滴出行平台技术部 taowen@didichuxing.com


引用和评论

0 条评论