目前团队人数很少,也没有真正意义上的
测试人员,那么如何保证代码质量呢?最近看了《持续交付——发布可靠软件的系统方法》很受启发,突然也想通了很多集成开发工具的设计理念,并做了一些实践,特别记录下来与众人分享。
如何保证代码质量
我觉得根本就是持续集成,确保代码服务器上的版本始终是可运行的。粗粒度上就是把功能分阶段做,每个阶段的功能是完整可发布的,这样有很多好处,尽早看到效果来调整、尽早发现bug、有成果可以鼓舞士气等等;细粒度上就是把每次提交的东西进行测试,让问题尽早暴露尽早修复。
如何达到这个目标呢?原则就是让重复的工作自动化,让测试频繁进行。具体来说就是自动化测试、自动化打包、自动化部署。
自动化测试就是为了能够经常反复的测试才能更早的发现问题。为了让开发人员勤于测试,所以测试的运行时间必须要够短。持续集成推崇的方式是每次提交执行一次测试,这里只做单元测试以确保速度,这也是为什么grails里面把unit单独拿出来鼓励测试。
自动化打包我没用高级的工具,就是利用ant+Ivy写的打包脚本,并借用Grails的思想,通过不同的打包参数可以打出dev、test、prod的包,这样就大大减少人工打包出错的概率。
自动化部署目前我用sae倒是平台就已经支持了,直接上传war包以后,部署都是自动进行的。但是sae的问题就是你本地测试通过的东西,那个环境却不一定行,无比尴尬。
测试种类与分工
测试种类的名词有很多,且最后用的都有很多歧义,特别是集成测试更是有多种含义。我觉得最好理解的划分就是:功能测试(单元测试,组件测试,验收测试)和非功能测试(探索性测试、性能测试、容量测试)。只要能做成自动化的就是开发人员做的;没有办法自动化的就是测试人员做的。
其中,单元测试是不依赖外部只测试某一个类的,为了达到这个效果还有挺多工作的,外部依赖的类要用Mock来模拟,并且尽量不连接数据库这些外部依赖。组件测试就是要有这些外部依赖了,也可以说成是功能测试。验收测试就是模拟用户行为做一系列操作,这个是在最终发布的时候做一次,确保用户使用的正确性。
但注意,每个测试间要做到互相独立,否则会大大增加维护难度。
我期望的效果
单元测试是好东西,但是其实我觉得组件测试是涵盖单元的功能,只是运行时间更长一点而已,但为了减轻测试代码的工作量,我想省去单元测试而全部采用组件 测试。组件测试有一个棘手问题就是用到数据库,而数据库是一个有状态的,测试运行的先后顺序都会影响测试结果,所以最好的办法是让每个测试执行完进行回 滚。
验收测试是个刚学习到的理念,就是把用户对某个功能的一系列操作放在一起进行功能效果验收。虽然会有很大维护量,但是可以有效模拟用户行为,对功能效果进行完整的测试,达到回归测试的效果。
总结一下,就是利用组件测试达到频繁测试的效果,用验收测试达到回归测试效果。
测试框架
为了达到以上效果有什么好的框架,我查了一圈资料,也试了几个框架。Junit4还是被公认最简单有效的框架,并且有众多的扩展插件和IDE支持,但缺 点就是自身功能过于简单。要实现每次测试完的回滚需要结合dbunit,要和spring集成也要自己实现,用到mock也有很多工具可选择。
最后发现一个整合的测试框架Unitlis,它不但整合了以上需求,还简化了配置操作,同时还实现了数据库升级文件的版本管理。试用以后感觉很不错,非常有爱。官方主页是:http://unitils.sourceforge.net/summary.html。
我觉得Unitils有以下几个比较显著的优点:
1、基于反射的断言非常强大,自动过滤掉null和空值,对数组也无视顺序,真的是基于内容本身的比较。
2、集成了spring管理,都是用注解来声明,非常清楚简洁。
3、集成dbunit,配置简化了很多配置,特别对事务回滚配置也很灵活、简单。
4、自带的Mock很好用,语法很漂亮,虽然暂时没打算用。