你好,我是李辰洋,是《徐昊·TDD项目实战70讲》的课程编辑。

如果你看完了目录和开篇词,心里估计会生出这么两个疑问:

这些都是好问题。归根结底,要回答上述疑问,我们就需要明晰TDD的学习难点在哪里。

如何搞定TDD?

从一项技能被使用和理解的难度上来看,TDD的复杂度是中等。更具体些来说,TDD的学习复杂度大致低于熟练掌握一门编程语言,高于学习一个框架或者类库。看起来,TDD的学习难度并不算大,那么为什么很多人还是没能学会呢?

TDD的一大学习困难点就在于,会TDD的人对其中的妙处有着非常强烈的主观体验,而不会TDD的人,则体会不到。所以最佳的学习路径,就是由熟练者来指导新人。那么课程的第一个设计亮点,通过视频的形式来演示用TDD实现项目开发的全过程。

设计亮点一:以视频演示为主,图文为辅

需要说明的是,视频是整个课程的核心构成部分,而不是多了一种交付形式来丰富内容。因为TDD的重点就在于跟着测试的步调来“驱动”开发。

我在课程设计之初进行调研时,有同学反馈说:

在团队里的新手学TDD的时候,我会让他们自己敲一遍代码,然后录个视频发给我。最后发现很多人做错了,他们都是先写实现再写测试。所以如果有视频的话,他们至少不会犯这个错误。

这实际上就是没有学会驱动。他的开发就只是开发,测试就只是测试,并没有把两者有机地结合在一起。而这个有机的组成部分,是没有办法用文字表达出来的,只能用视频来呈现。归根结底,必须通过视频,来体现使用TDD构造软件的过程。跟着老师在视频中演示的思路走,重现测试“驱动”开发的时间线。

事实上,徐老师在录制视频时,也只是走一遍时间线确定下时间,然后就开始录,并不会修改什么步骤。

顺便说个题外话。在课程设计之处,徐老师就表明这次课程会是视频为主的内容交付形式。起初我一直无法理解,为什么不能用文字来总结,说明使用TDD来实现功能需求的思路。后来找了位开发小哥,坐在他旁边看他跟着徐老师的视频敲代码,然后再看着他自己演练,终于感知到了几分意思。

而文字部分呢,侧重于总结视频演示重点,以及梳理TDD学习中的相关问题。所以在学习的过程中,非常建议你将视频与文字结合起来,学习效果会更好。

设计亮点二:以三个技术框架为核心,而非玩具项目

想要搞定TDD,另一个需要突破的障碍则是实战中的细节。这意味着你要在复杂场景下反复练习,才能学会怎么在不同的上下文中去应用。针对这一点,我们设计了四个实战项目。

其中第一个项目是演示参数行命令解析的例子。这个例子源自Bob大叔那本广为流传的书——Clean Code。这是一个编程练习级别的例子,非常简单。目的是让你眼见为实,亲眼看一看真正的TDD是怎么驱动开发的,从而对真正的TDD有个感性且直观的认识。

在这个项目之后,我们将进入TDD的完全实战环节,老师会带着你使用TDD的方式去实现工作中常用的3个技术框架,包括IoC容器、RESTful、SQL mapper。

之所以选择技术框架,而不去虚构某个业务系统,主要是因为TDD的难点首先在于理解需求,并将需求分解为功能点。

如果去虚构业务系统,那么我们很难详尽描述所有的业务假设(功能上、组织上、运营方式上等)。但如果使用一些常用的技术框架,由于你对它们大体的功能及其要解决的问题,已经有所了解。所以老师不仅不用花那么多的时间来啰嗦上下文,同时也有利于你跟随题目自行练习。

当然,这三个技术框架的难度会高于你在实际工作中所使用的。因为搞定TDD的关键就在于在复杂场景下反复练习,最终学会怎么在不同的上下文中去应用。

该怎么学习TDD?

TDD的学习难点首先在于理解需求,理解需求,并将需求分解为功能点。而最佳的学习路径,就是跟一个真正会TDD的程序员来学习。

那么看看视频、跟着敲敲代码,能学会TDD吗?显然不能。要知道,课程中的所有代码,我们并没有放在GitHub或者Gitee上。这样做的意图在于,希望你能在观看完徐老师的演示视频之后,开动下自己的小脑筋,亲自动手再去写一遍。写完之后,可以将你与老师写的代码进行对比。这个有效的学习方法也可以总结为“一看二动三对比”。

另外,徐老师特地邀请了他Thoughtworks的两位同事作为课程的审稿人,分别是王晓峰老师和郑茗蔓老师。茗蔓在学习审核的过程中,也收获了一些思考。下面是她的分享:

我大概是在2020年接触的TDD,那时只知道TDD是一种先写测试再写实现的开发方式。但越简单的道理,实践起来就越是困难。在最初实践TDD时,我经常碰到的一种情况是:拿到新的功能需求后,通常在第一个测试就会直接断言这个功能期望的输出。这样做的结果是,用一个测试驱动了一整个功能需求。
 
可想而知,如果这个功能很复杂,那我首先需要花大量时间去构造测试,然后再花费大量时间去试图一口气完成整个功能需求。这种做法显然没有理解TDD中的“编写一个无法通过的测试”原则,也不知道这个测试到底需要什么样的粒度。
 
在学完第一个实战项目后,我之前的很多疑惑都得到了解答。测试驱动开发,从名字上看很容易误解为不过是调换了写实现代码和测试代码顺序的一种开发方式,但实则不然。通过先写测试来不断地对自我进行验证和提问:对需求是否了解?对当前项目架构是否了解?当前架构是否到了需要演化的时间节点?来加强自身对需求和架构的关注,进而达到优化架构的目的。徐昊老师从各个方面系统地阐述了测试驱动开发到底是什么。因此,通过本门课的学习,让我更为全面地了解到了什么是测试驱动开发。
 
在老师视频演示敲代码时,我也会跟着敲一遍。对于课程内容,我会先整体浏览一遍,跳过不理解的地方。然后再拉通整个小节的内容,试图理解老师讲述的逻辑,并进行总结与记录。有时候也会反复翻看之前的课程内容,总是常读常新。有些之前不懂的地方,来回多看和思考,慢慢就明白了。

编辑寄语

最后,我还想讲两个题外话。首先,在这里,我也非常感谢晓峰和茗蔓勤勉的审核工作,以及专业的合作态度。在我看来,他们都是软件匠艺的追求者。他们为了提出一个好问题,甚至需要查阅好几篇文献,为我们课程内容做了非常严谨且专业的技术审核工作。

第二个题外话。在这么大的课程容量下,还要建议你采用“一看二动三对比”这样的学习方式。可以预见到,这会让你花费不少的精力,而完全坚持下来也有些困难。

所以我们目前策划了如下活动,来尽量保证你的学习效果:

  1. 建立微信群。我们的运营同学会组织活泼严肃、团结紧张的学习打卡活动。
  2. 我们目前还在策划一个“线上带练”的学习项目。由徐昊老师亲自带队,手把手教你怎么在实战中练习TDD。预计4或5月会开启。
  3. 不定期举办一些开奖活动。

三月春风,柳色初青,一年之计正在于此。欢迎你加入TDD的学习!正如在《如何落地业务建模》中所做的那样,编辑的其中两个角色定义是“程序员的鼓励师”和“解决方案提供者”,所以如果你有什么关于TDD学习的疑惑,或者对于课程的想法,欢迎你反馈给我!

好了,接下来,欢迎你在评论区自由发言!徐老师在评论区等着你!