《Effective Unit Testing》 读书笔记 7 可维护性 code smell

说实话,大部分程序员的工作都不是在写新的代码,而是在改写已有的代码(也包括自己写的),代码的特点是无比灵活又非常脆弱,因此可维护性的重要性不言而喻。下面是这章罗列的一些可维护性方面的code smell。

  • 重复
    这点不用多说了。作者罗列了三种类型的重复:字面重复,结构重复和语意重复。不过如果过于抽象导致影响可读性,也可以适当保留重复。

  • 条件判断
    就是不要在测试中用if while之类的条件判断语句,尤其是不能把assert放在条件语句中。在一种条件下assert这个,在另一种条件下assert那个,这会导致代码不容易看明白,还会导致测试失败了不看源代码不知道为什么失败。解决方法,对于不同条件的断言直接分成不同的test方法。

  • 不可靠的测试
    不可靠的测试是指由于测试依赖了系统时间,随机数,系统速度,并发时哪个线程先完成,外部网络之类不确定条件,从而导致结果不确定的那些测试。解决方案是避免,控制,孤立。

  • 有危害的文件路径
    指在代码中写死的绝对路径,为何对可维护性有害很容易理解,测试难以迁移(不同的操作系统,机器)。解决方法建议尽量用相对路径,或者放在同一个package下面通过getClass().getResource(“example.xml”).getFile()的方式来获得。更进一步说,在设计我们api的时候尽量不要去基于File作为参数,而要使用InputStream, OutputStream。

  • 被保存的临时文件
    指在测试中会在系统中生成一些临时文件并依赖这些文件。这很容易造成各种乱七八糟的错误。最好是完全避免测试依赖于文件系统中的文件,因为1. 文件系统慢,2.文件和整个操作系统其他进程共享,指不定会被谁改动。如果一定要依赖文件(比如就是测试写文件功能的),请显式得在测试一开始删除这些文件以确保不存在。

  • 睡着的蜗牛
    简言之避免任何Thread.sleep的测试代码。测试多线程并发的代码,可以考虑用java.util.concurrent包下面的工具类,比如latch。

  • 像素级精确
    一种特殊情况的原始断言或者超级断言。主要在图像软件输出的测试中,去比较输出的图像在像素级别上是否完全正确。这导致测试非常脆弱,一点小改动可能要改整个测试,而且别人也看不明白输出为啥必须这样。怎么解决呢,需要写代码去抽象识别图像的输出,当然这也挺不容易。

  • 搞糟了的参数化
    JUnit带有参数化测试方法的功能,最好就是不要用,多套参数自己去组织数据结构。具体不说了。

  • 方法缺少内聚性
    诊断很容易。我们的测试类通常需要一些成员变量作为fixture,如果这个测试类里有好几个测试方法,那这些测试方法都应当使用到全部的fixture,如果有测试方法只用到这个类里fixture的子集,说明这个测试方法就不应该和其他方法一起放在这个测试类里,或者说这个测试类里的测试方法缺乏内聚。
    解决方法就是要拆分出多个测试类,或者每个测试方法的fixture写在各自方法里去初始化。对于重复部分,可以通过子类或者util类来实现。从实际经验看,这点挺难遵守的,因为开发人员会图方便或者不愿创建很多类。但是一旦这个类变得很大,维护起来的确会令人头痛。

下一章将介绍影响可靠性的code smell。

你可能感兴趣的:(《Effective Unit Testing》 读书笔记 7 可维护性 code smell)