程序员如何培养好的测试习惯?
软件开发周期通常至少有以下4个步骤:需求分析,软件开发,测试,部署。而其中的测试是我们今天要说到的重点,今天我们来聊一聊程序员和测试这件事。
现状
目前大部分软件公司或者IT部门是没有配备专门的测试人员的,测试通常依靠程序员自测,公司内部人员测试,自动化工具测试等等。
在没有测试人员的情况下,其中最重要的环节其实是程序员自测。我们知道好的软件并不是一蹴而就的,而是一步步迭代而成。而在迭代过程中如何有效保证软件质量和项目周期,就离不开测试。
认清测试的重要性
在认清测试的重要性之前我们先了解一下软件项目管理金三角具体是什么。
我们都知道大部分情况下软件项目想要同时满足:“多、快、好、省”是不可能的,一般只能占两样。而在软件项目中,也有一个类似的平衡关系,就是软件质量(产品的质量,客户的满意度)与范围(需要实现多少功能)、时间(多久可以完成)、成本(花多少钱)四个要素之间的平衡。《软件工程之美》-宝玉
我们可以看到质量是放在中间的,因为软件工程的目标就是要构建和维护高质量的软件。而很显然,想要提高质量必定离不开测试。没有完善的测试,我们就不能确保交付一个高质量的软件(高质量的编码是目前很多程序员还达不到的一个要求)。
看到上图肯定会有一个问题:时间和成本被压缩的情况下,我们怎么能够保证质量?
成本低可能我只够招到合适的开发,而专业的测试人员这一块我们只能放弃。时间紧张,那么我可能并没有时间实现一个自动化测试工具或者说对每一份代码都写上单元测试。
很多时候,实际情况确实如此。但这并不是我们简化测试的理由。我个人认为:单元测试在敏捷开发模型中是必不可少的一部分(瀑布模型中留有足够的时间给到测试),因为敏捷开发模型是小步快跑,逐步迭代的。在项目的整个开发过程中,如果没有配合一定量的单元测试,那么越到后期测试的压力越大,耽误的时间更多。从长远来讲是不划算的。
也有人说,我用敏捷开发模型的目的就是更快推出最小可行性产品,让市场或者说种子客户验证产品,完善产品。如果纠结于完善的单元测试岂不是浪费我宝贵的时间?
上面我们提到了时间、成本、范围和质量的关系。我们这里可以通过压缩范围来获得时间,给测试留出空间,优先实现核心功能的单元测试。毕竟你出于对自己的代码的负责性,总归是要测试的。不管你是自己点点点还是通过接口工具一类来测试,效果都不如编写一个完善的单元测试来的更划算。毕竟这功能你可能不止要测试一次,以后业务变更可能还需要测试,这时候你可能会忘记来测试这个功能,而单元测试能帮助你避免这个问题。
自动化测试的分类
自动化测试按照Google的分类可以简略分为3种:小型测试、中型测试、大型测试。
小型测试是为了验证一个代码单元的功能,例如针对一个函数或者一个类的测试。上文说的的单元测试就是一个典型的小型测试。
中型测试是验证两个或多个模块应用之间的交互,通常也叫集成测试。
大型测试则是从较高的层次运行,把系统作为一个整体验证。会验证系统的一个或者所有子系统,从前端一直到后端数据存储。大型测试也叫系统测试或者端对端测试。
而这里对应程序员自测最基本的要求是能够完成单元测试。要想提高自己的代码质量,单元测试可能是最容易实现的一种方式。因为他不需要你再去学习其他知识就可以提高代码质量,你只用完善单元测试,发现问题,解决问题,这样就能培养出好的编码习惯。
如何培养好的测试习惯
首先一定要培养写单元测试的习惯。但凡写完的代码都需要自己测试的情况下,优先考虑写个单元测试来查验代码的准确性。至于时间成本的问题大家可以自己考虑,毕竟现在单元测试框架都十分的完善了,这并不会花你太多时间。
然后我们再看看在编写一个完善的单元测试的过程中,我们应该考虑的问题:
- 验证功能的正确性
- 覆盖边界条件
- 异常和错误处理
然后更深层次的考虑是我们在编写代码的时候就要考虑代码的可测试性,常见的关键点有以下几个:
- 代码中包含未决行为逻辑
- 滥用可变全局变量
- 滥用静态方法
- 使用复杂的继承关系
- 高度耦合的代码
以上几个关键点如果有兴趣的同学可以自行去极客时间专栏《设计模式之美》中学习。