单元测试的优点与基本原则
单元测试,是指对程序中的最小可测试单元进行验证,在Java中的话,就是类。其有两个目的
- 验证程序实现的逻辑是否与设计的逻辑正确
- 在涉及到代码修改时,用单元测试去保证原有功能不被破坏,
而一个好的单元测试应该具备以下FIRST 原则和AIR原则中的任何一条:
单元测试的FIRST 规则
Fast 快速原则,测试的速度要比较快,
Independent 独立原则,每个测试用例应该互不影响,不依赖于外部资源。
Repeatable 可重复原则,同一个测试用例多次运行的结果应该是相同的
Self-validating 自我验证原则,单元测试可以自动验证,并不需要手工干预
Thorough 及时原则 单元测试必须即使进行编写,更新,维护。保证测试用例随着业务动态变化
AIR原则
Automatic 自动化原则 单元测试应该是自动运行,自动校验,自动给出结果。
Independent 独立原则 单元测试应该独立运行,吧相互之间无依赖,对外无依赖,多次运行之间无依赖。
Repeatable 可重复原则 单元测试是可重复运动的,每次的结果都稳定可靠。
一个整套完善的单元测试可以保障后续的增添功能时,程序迭代过程中,代码的逻辑正确性。验证程序的输入和输出与最初设计一致。这对后续的集成测试等会提供巨大的帮助。同时也会有利于集成测试的顺利进行。
单元测试的粒度应该如何选择
一个好的单元测试基本上应该满足上面讲到的FIRST 规则和AIR原则,然而关于单元测试需要覆盖到那些层级,覆盖到那些点,这个直接和写单元测试所花费的时间相关。所以一个团队应该要考虑单元测试的粒度,以及单元测试的代码覆盖率。
关于单元测试的粒度,可以总结以下几点:
- DAO层的单元测试: 对于基本CRUD,可以考虑跳过这一部分单元测试,而一些比较复杂的动态更新、查询等操作,建议用使用H2去做模拟单元测试。
- Service层的单元测试:基本上一个Service里面肯定会依赖很多其他的service(此处也建议将成员变量通过构造方法进行注入,以便于单元测试去Mock),此时建议我们将依赖其他service的方法用Mock替代,Service里面的一些数据库的操作也进行Mock。这样可以保证service测试的独立性,不过对于逻辑复杂的方法可能要花很多时间在Mock上面。 如果发现需要Mock的方法过多,那么可能就需要考虑将要测试的方法是不是需要重构。
- Controller(API)层的单元测试:主要着重测试HTTP status在 200,400,500 等情况下的异常处理,request及response的转换等。由于其余部分的代码测试都已经在其对应的单元测试覆盖,那么此时可以Mock绝大部分Serivce层中的方法。
- 一般工具类的单元测试:一些工具类里面包含了比较多的逻辑,所以需要尽可能考虑多种情况下测试用例。
发表回复