Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TDD 周报三「作为个人工具和团队实践的 TDD」 #177

Open
EthanLin-TWer opened this issue Jun 16, 2017 · 6 comments
Open

TDD 周报三「作为个人工具和团队实践的 TDD」 #177

EthanLin-TWer opened this issue Jun 16, 2017 · 6 comments

Comments

@EthanLin-TWer
Copy link
Owner

EthanLin-TWer commented Jun 16, 2017

上回我们总结了 TDD 的 四个优点。和肖劲交流过许多问题以后,我们再把 TDD 的主要优点归结到两个:

  • 效率
  • 重构

重构

先讲重构。这是一个团队问题。和肖劲聊到,TDD 产出的单元测试,既是开发人员之间交流业务理解的 single source of truth,也是重构时的绝佳和唯一保障。没有测试,做卡时的业务知识就随时间和人员变动流失;没有测试,无法重构,就会越不敢动原来代码,越往上堆,关注点越多,业务耦合越复杂,质量越差, 越不可能测试和重构,整个项目,一定会腐化,腐化到新功能难以加, bug 难以完全修复,开发体验及其糟糕。一定会变成这个样子。所有悲剧都是从没有测试,没有 TDD 开始的。你说具体情况具体分析,你说可用可不用的时候,就是在给项目挖坑了。

因此,先不讨论测试先行还是后行的问题,可以肯定的是,没有测试,辅以时日,一个项目100%会烂掉,变成巨坑。

而测试,只是为重构提供了这样的土壤,要让项目持续保持清爽整洁的状态,还要求你 会重构频繁随手进行重构。不会重构没什么,可以学,测试就是 single source of truth,只要测试绿,重构就不会出问题,重构得好不好,可以慢慢学。这里,测试作为一项团队实践,事实上要求每位团队成员不断提高以下四个方面的能力:

  • 写好测试的能力(健壮的 TDD 方式,关注接口和业务,胜于实现和细节)
  • 对现有代码库和技术栈架构的理解和编程能力(巧妇难为无米之炊。实现都不知道怎么写,还怎么谈驱动)
  • 重构的能力
  • 设计的能力

这些都是其他的课题,需要另外的学习,与 TDD 这个工具并行使用,方可发挥出神妙之力。这是道长举过的例子,一把雨伞,在普通人眼里可能就只是一把雨伞,可是到了成龙手里,它就是一件武器,一件取人性命的利器。

那也就是说,测试写不好(测实现而非业务价值),用了 TDD 也不能写出好的测试;不会重构,只能保证项目不变差;不会设计,TDD 也不能帮你驱动出好的代码。用 TDD 的同时,要同时加强这四个方面的能力。

效率

后说效率。我一直在自问这个问题,也问了肖劲:如果说,TDD 只是一项对团队才有利的工具,测试只是作为沟通和重构工具,那么,在你的个人项目里,去掉团队这个因素,你还会使用 TDD 吗?也就是说,抛开团队实践不说,TDD 能同时是个人实践的好工具么?它用起来让你真实地感觉爽了吗?

我是 TDD 的脑残粉,我自己当然觉得提高了效率。这个效率,我无法量化,但并不阻止我去实践它。简单说来,我感受到的效率提高,主要有以下几方面:

  • 减少了开发无用需求的浪费
  • 减少了脑力的分散
  • 减少了回归的成本

无用需求的浪费。TDD 的前件是一个「任务列表」,不在列表上的,绝不多做;在列表上的,绝不能少做;没有紧紧抓住这个「任务列表」,仅凭我「觉得」可能需要这样的本能来做事,可能会多做直觉有用其实没用的事,或者少做一些本来需要做的事。

减少脑力分散。脑力资源特别宝贵。TDD 使得你从原来的「做这个卡需要做这 n 件事」,变成现在的「只需严格按任务列表推进,一次一个 todo,以测试通过 - 没有坏味道作为唯一验收点」。一套完善的 tasking+todolist 系统,可以让你从 n 个需要追踪的问题上解放,一次只需要专注于一个任务,并且有唯一的验证标准:测试通过、没有坏味道。这是可执行、可验收的,并且是符合人脑认知规律和限制的:一般人的大脑工作记忆里,只能存放四块不相关的东西,把编码工作打包成「实现测试、去除坏味道」一个单元后,解放出了其他三个单元的工作区,让你能提升速度、思考效率,从而思考更多的问题,更快成长,有更多时间去做更有意义的事。如果你总是在 debug,一行行追踪这个变量是不是0,那个变量是不是空,是不是该传入数组而传入了一个对象,你的大脑就浪费了很多资源在这些低层级的任务上,并且成效很低。每天加班到天明不是一个传说,经历过的看过的人能知道,这样的「程序员」生活只能让你感到痛苦和没希望,时间长了谁也扛不住。

减少回归成本。已经完成的任务有没有改挂,有自动化测试作为 single source of truth;写一段逻辑,再也不用嵌入到浏览器的 console.log() 去手调验证;修了个 bug,能快速回归以前的功能,保证测试通过、坏味道消失。

可以说,这些实践都是围绕专注于单个有价值的目标展开来提升效率的。自动化测试在其中扮演了一个提供零成本、极快速验证的角色。谈 TDD 时,我一直在谈 single source of truth。思维一定要转变过来。把原来那种符合直觉、「眼见为实、手动验证」但低效痛苦的反馈方式,慢慢迁移到以「自动化测试是否全过」、「坏味道是否全部消失」作为唯一真理的思维方式上来。依赖于自动化的测试设施,你的回归成本几乎降低到0,还有时刻的测试绿条给予正面反馈,

以上,要让 TDD 真正成为你手里的利器,你需要不断锤炼这四方面的能力、意识和工具:

  • 任务分解(tasking)的能力
  • 与任务列表紧密配合的 Todolist 系统以加速工作流的能力
  • 获取更快速反馈的能力
  • 向更高阶思维的转变

从不停止追求卓越,这就是我 TDD 的理由。以上8个维度的能力,会是我接下来的学习方向。

下一步产出

这个项目上,我要去实践,从上面框架、8个问题来发现自己弱点、发现痛点,解决这些痛点,形成一套行之有效的工作流,并产出一篇博客。落地上,需要解答的问题有:

  • 团队实践具体如何落地(从上往下推,测试策略、关键测试覆盖、底线制定等;dev 自发日常使用快捷键、命令行、TDD,形成氛围,把测试实际的好处、质量提升、效率提升秀出来,让大家在潜移默化里来感受、尝试接纳,而非光讲道理)
  • 什么是好的测试(关注业务价值胜于技术细节、断言接口返回胜于具体实现、先写测试胜于后写测试)
  • 如何重构、如何学习重构、如何评判重构好坏
  • 如何 task、什么是好的 task(完全、穷尽、正交)、如何不断反馈修正任务分解和工时估计(PDCA)
  • 如何定制一个适合自己的 todolist 系统、并与任务分解、TDD、重构等形成一个行之有效的工作流(IDE todolist + Sublime 双屏)
  • 如何在工作流的每一步获得更快速的反馈(保存文件即运行测试、双屏、更好的断言库 power-assert、git hook 在提交阶段拒绝挂掉的测试而非允许其流入下游)
  • 具体到代码库的架构下,如何确定测试策略、如何写好测试
  • 有什么具体的坑、有什么解决方案
    • Promise、async测法 -> 异步多用框架提供的 done() 支持,Promise 可采用 mock + then + done() 的方式
    • API 调用、IndexedDB 调用 -> mock 呗,多好解决
    • 数据准备困难,需要对业务流程、数据结构有较多了解才能写好 TDD 的输入部分 -> 工作个一两周,熟悉了业务和数据结构后就顺手了,没什么捷径可抄要抄
    • 部分代码实现依赖于框架的生命周期及次序等,这玩意很难测(虽然一兮和志桐一直说可以测~) -> 有待探究
@JimmyLv
Copy link

JimmyLv commented Jun 17, 2017

特别棒!

@EthanLin-TWer
Copy link
Owner Author

EthanLin-TWer commented Jun 17, 2017

@JimmyLv 四个点四个点的无序列表,真是前端时代一个媚俗的写作方式啊,我都看不起我寄几~

@EthanLin-TWer EthanLin-TWer changed the title TDD 周报三 TDD 周报三:作为个人工具和团队实践的 TDD Jun 18, 2017
@EthanLin-TWer EthanLin-TWer changed the title TDD 周报三:作为个人工具和团队实践的 TDD TDD 周报三「作为个人工具和团队实践的 TDD」 Jul 30, 2017
@JimmyLv
Copy link

JimmyLv commented Jun 26, 2018

我在思考TDD好处的时候也是从三个方面:

1. 效率

  • 提前确认需求,减少浪费
  • 小步快走,缩短反馈周期

2. 架构

  • 演进式设计,持续重构
  • 面向接口编程,合理架构(松耦合高内聚)

3. 质量

  • 高测试覆盖率(只测该测的)
  • 自动回归测试

但总感觉措辞还是弱了点,可以帮忙归纳、补充、润色么?

@JimmyLv
Copy link

JimmyLv commented Jun 26, 2018

把TDD的level上升高于UTDD,便会想到团队、想到架构,然后搜了一下发现:

特别是还有这篇:

TDD 会破坏架构吗?:作为敏捷宣言的共同作者,我们熟知的鲍勃大叔 Bob Martin,在最近发表的一篇文章中对 TDD 是否会损害架构进行了评估。文中大部分讨论围绕着遵循测试驱动方法对高层设计和实现代码的总体可维护性是否会产生消极影响。Martin 认为,虽然 TDD 是重要的守则,但良好的设计来源于解耦、分离和隔离等原则。

@EthanLin-TWer
Copy link
Owner Author

少年是自己学习用还是做推广用呢,如果是后者的话,估计我给不到什么帮助。

一来自己最近处于去敏捷的阶段,二来是诸多总结以后我觉得,总结它,教授它,对掌握 TDD 这项技能本身并无太大帮助。重在练习。知道它与架构的关系,知道它能快速反馈,也不如真正撸代码快速反馈一把。我感觉它最后应该是变成阳光或水一类的存在,它的手法、思想、快速反馈,贯彻你思考、击键的始终,但你没有特别的意识,没刻意知道说哦这就是反馈这就是架构。

有种说法者无法可说的感觉,所以确实不知道如何润色。语无伦次了。

非要有个说法的话,我觉得可以去掉「质量」一小点,抓住「重构」和「效率」两方面。「质量」、「架构」是初学者用了 TDD 也不会感知到的部分,而重构和效率关系则很密切,也容易感知。因为你要重构,所以不得不有测试;因为你想提高效率,才会快速反馈、小步快走、确认需求减少浪费、快捷键等东西出来。

@JimmyLv
Copy link

JimmyLv commented Jun 26, 2018

其实「质量」这一点也是对于团队来说的,质量可以有这样一个切入点,就是团队不同角色之间的沟通,QA找出bug了才回来找Dev沟通,如果没有bug就不会有什么纠葛。然后Dev很烦QA来找自己,因为那样对自己的效率影响很大,然而自己又没办法在QA发现之前找出bug,那自然测试先行可以算作一种更为可靠的自测方案。如果QA能够更加与Dev协作于ATDD,那自然整个团队的沟通“语言”变成了代码、有了更高一层的自动化,代码即语言,通过技术方案解决沟通问题,进一步降低沟通成本。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants