代码整洁之道(Clean Code) 笔记(三)

第八章:边界

本章关于如何学习使用第三方组件

  1. 第三组件或框架追求普适性,而使用者则想要集中满足特定的需求
  2. 学习第三方组件首当其冲当然还是文档,其次重要的是它的单元测试,我甚至是把单元测试当作文档的一部分来看待。其实更重要的方法是学习性测试(learning tests), 通过测试来学习才是切实的体验,是一种精确的试验,我们甚至可以用自己的测试来验证第三方组件的新版本
  3. 边界上会发生有趣的事,这就要求我们对它清晰的分割和定义,以避免我们的代码过多地了解第三方组件中的特定信息,依靠你能控制的东西好过依靠你控制不了的东西,免得日后受它控制。简而言之就是尽可能隔离边界,在边界改动时只需要修改一下适配器,对的适配

第九章:单元测试

这一章我自认为是很重要的,特别是正在采用测试驱动开发/设计(TDD) 的程序员来讲。充分,良好的单元测试是保证我对生产代码大刀阔斧的关键,这也就是 TDD 的最后一个 D 又能理解了 Design 的原由

  1. 单元测试最初可能只是用来替代纯手工测试的用过即扔的短代码,但后来逐渐体现出它的重要性,成为驱动开发/设计的很重要的一环,是让我们的代码能够精益求精的关键,反正我是非常依赖完整的单元测试
  2. 虽然敏捷和 TDD 运动鼓舞了许多程序编写自动化单元测试,但不少程序员编码的习惯仍是写完整套可执行的代码,手工做完集成测试后再补单元测试,似乎整个流程跑不下来单元测试存在的意义不大; 而我则认为充分的单元测试给予我们足够的信心去进行集成,更何况外部某些接口尚未就绪时需要我们进行 Mock 而不能由此中断开发的进行
  3. TDD 三定律:1)在编写不能通过的单元测试前,不可编写生产代码; 2)只可编写刚好无法通过的单元测试,不能编译也算不通过; 3)只可编写刚好足以通过当前失败测试的生产代码。这三个定律执行起来还是比较难的,应该还未到达这个境界
  4. 测试代码和生产代码一样重要。因为测试代码必须随生产代码共同演进,如果单元测试很脏,难以修改它们就可能有被抛弃的命运,而一旦没有了单元测试的保驾护航,回归到以前,生产代码就要失去可扩展,可维护,可复用的特性,任何企图对生产代码的轻微修改都像是高空走钢丝
  5. 整洁测试的要素是可读性,它的可读性甚至比生产代码还重要,因此我常常把单元测试看成是最可靠的 API 文档,当不清楚某个方法如何使用时,看单元测试
  6. 单元测试的三个环节:构造(BUILD, 又称 GIVEN): 构造测试数据;  操作(OPERATE, 又称 WHEN):操作测试数据;  检验(CHECK, 又称 THEN):检验操作是否得到期望的结果
  7. DSL(面向特定领域的语言) 写单元测试会令人更舒服。例如 Java 挣脱不了方法名的规定,camel case, 或最多能加入下划线来组织具有描述性的用例名。TestNG 可以用 @Test(description="...", JUnit 5 才能用 @DisplayName 来输出更具描述性的用例名。如果是 Scala 那样的语言就简单了,用以用 ScalaTest,或是斜撇号括起来的方法名,即使含有空间都能作为方法名 def should return 3 when 1 plus 2 {...}
  8. 使用 Java 编写单元测试时, JUnit 本身的断言方法实在是不好用,且写起来不够流畅,比如 assertEquals(arg1, arg2) 经常有人会把实际值放前面。所以断言推荐用 fest assert 或 AssertJ. fest assert 在  2013 年后就停止的更新,AssertJ 是 fork 自 fest assert, 最近一直在更新,所以我改主意了,重点推荐 AssertJ
  9. 测试 API 中的代码与生产代码相比,的确有一套不同的工程标准。测试代码应当简单,精悍,足具表达力,但它该和生产代码一般有效
  10. 有个流派认为,JUnit 中每个测试函数应该只有一个断言语句,这个做法过于苛刻也不切实际。最佳规则就该是尽可能减少每个概念的断言数量,每个测试函数只测试一个概念
  11. 单元测试的 F.I.R.S.T 规则.
    Fast: 测试要快,才能频繁的运行它,才乐意在 push 代码之前运行所有测试
    Independent: 单元测试间不应用任何依赖,那个 JUnit 的 @FixMethodOrder 设计的初衷可能是能让单元测试按照某种顺序来显示,但无形中可能造成实际执行顺序的依赖,本人不推荐用这个注解
    Repeatable: 测试应当在任何环境中重复通过,也就是说没网络也行
    Self-Validating: 失败时描述信息要足够详细,尽可能不用去输出日志/异常栈中找错误原因
    Timely: 测试应及时编写。如果在编写生产代码之后编写测试,你会发现生产代码难以测试,进而可能放弃对该部份生产代码的测试

本文链接 https://yanbin.blog/reading-clean-code-note-3/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

2 Comments
Inline Feedbacks
View all comments
mashiguang
mashiguang
6 years ago

这本书后边还有内容吗?