许多人提到“单元测试”,实际是指组件测试、集成测试,甚至是用户验收测试(UAT),这通常会在软件工程中导致很多混淆。一言以蔽之,“单元测试”就是针对一个工作单元(对一个方法的一个要求)设计的测试。
其特点:
与其他代码隔离
与其他开发人员隔离
有针对性(单一职责原则)
可重复
可预测(给定输入,得到指定输出)
并非那些跨过被测类与方法边界的测试就没有价值,一组代码如果不能被继承到一个更大的系统中,其价值就是很有限的。
按特征划分工作单元,完成单元测试,创建继承测试。(座右铭:早集成,常集成)
TDD(测试驱动开发)使用模拟的最佳实践:
依赖项注入(Dependency Injection)——在对类进行内部实例化时,不是静态创建该类的所依赖的对象,而是向其提供这些对象的一些实例,这些实例符合该依赖项所需要的接口。在创建对象时,应当将这些实例作为构造函数实参传递给对象。这样就可以很轻松地用模拟对象来代替实际对象,供完全集成的应用程序使用。
为接口设计,而不是为实现而设计——在将另一个类或资源用作依赖项时,应当关注的不是它如何执行自己的任务,而是关心其接口是什么。
尝试限制依赖项——大多数代码都需要依赖于某种东西。大量的依赖项不仅会意味着一个脆弱的系统,而且这样的系统也很难进行有效的模拟和测试。
不要模拟私有方法——不要过多的进行模拟。模拟私有方法需要了解所模拟服务的内部功能,这也不符合封装原则。
不要欺骗——不要用模拟走捷径,否则可能损害测试,进而使软件受损害。
没有代码是完美的。利用重构,可以持续不断地修改和改善所编写的代码。常见的编码与设计问题,通俗的说就是“代码异味(code smell)”
单元测试有助于确保:无论以重构的名义进行了哪些修改,这些代码都仍然能够满足业务需求。这便是“无畏重构(fearless refactoring)”一词的出处。
代码(测试)覆盖率可以快速揭示哪些内容没有使用,以检查是否需要这些字段。
使方法更简短、针对性更强,可以降低代码的复杂性和出现错误的可能。
编写了更多代码行的原因,可能是重复提供了在应用程序其他地方已经存在的功能。(不要重复自己——DRY理念)
OOP原则
OOP(Object-oriented programming)是一种方法,用于将现实世界的对象抽象为可供代码使用的类。其思想是:如果可以在代码中建立业务问题的模型,那就可以更轻松地创建能够正确解决这些问题的应用程序,而且其解决方法能够更好地反映现实世界。
OOP三大原则:
1.封装
创建的类应是黑盒。
2.继承
过度应用继承也不应该。继承树过深,可能会导致新的复杂度。如果分层结构的中间层的某个逻辑单元必须加以修改,会导致整个代码变得脆弱、难以修改。在某些情况下,应当优选“组合”而不是“继承”。
3.多态(Polymorphism)
注释——除非是编写设备驱动程序,或其它某种“不再修改的”代码,否则代码中的注释也是一种代码异味。优秀的代码应当是整洁而易于理解的。