|
2017年12月31日做一次技术总结,人生第一次
框架选型:assertJ+Junit+powemockito+mockito+maven/ant/gradle+jacoco+jenkins+sonarqube
单元测试中,要测试目标模块的时候比如测试service方法的时候,service方法中我们有可能会去调
用数据库的执行结果,会取redis中缓存数据,也有可能会使用当前的系统时间,根据系统时间做一
些逻辑处理,造成被测方法对外部有很强的依赖关系。假如被依赖的方法还没有开发完成或者预期输
出有问题,就会造成被测方法单元测试失败。单元测试的思路就是我们在不涉及依赖关系的情况下
测试代码。这种测试方式可以让你无视代码的依赖关系去测试代码的有效性,具体就是使用mock
技术,模拟被依赖的组件的行为。
controller,service层及util工具类使用mockito和powermockito
dao层使用,一开始想着在不依赖数据库的情况下就行测试,所以就使用了h2内存数据库,但是实际
写的时候由于数据库类型的不同,很多sql语句使用了特定数据库的特定函数,导致一些sql不能测试。
前端js的单测没有涉及
环境搭建:
1). 搭建sonarqube+maven+jenkins
jenkins加节点,随着jenkins构建项目的增多,单个项目构建时间从一分钟到十几分钟不等,当同时
多个项目代码有提交更新触发构建的时候会有大量任务排队等待。
maven配置文件,添加sonar的地址配置,执行maven构建后sonar会自行去进行静态代码扫描及单
元测试分析
2). 项目中配置单元测试相关的东西
ant构建:参见官网 http://www.jacoco.org/jacoco/trunk/doc/ant.htmldebug模式,srccompile和
testcompile需要分开写;编译需要开启
maven构建:添加jacoco插件、断言和mock相关jar包依赖配置
3)jenkins添加构建项目
sonar执行单测分析的时候会去默认的路径下面找jacoco.exec.所以当你的项目自定义了jacoco生成
jacoco.exec的路径的时候需要制定jacoco.path
构建完成后soanr会统计出单元测试用例数,覆盖率,失败率等信息,具体的数据指标sonar数据库
有一张单独的表每个字段对应一个指标,数据表中会对应每个指标字段有对应数据
代码编写:
a)创建测试类
命名规则*Test.java,测试方法的名称必须能描述清楚测试目的
b)用例设计(最重要的部分)
单元测试不只是语句覆盖,分支覆盖,更多的应该从功能的角度去设计,100%的语句全覆盖率并
不代表100%的功能覆盖。单元测试的价值在于在进行减少功能测试阶段的bug数,从而减少版本
迭代次数,提高效率。如果不能做到好的用例设计,只是单纯的为了覆盖而去覆盖意义不大。
c)创建mock对象
d)mock方法
方法中new对象;final方法;静态方法;私有代码块;私有方法;系统类的静态和final方法;枚举
类;spy;whitebox测试私有方法;
e)mock校验
f)junit校验
使用assertJ,校验强度要适中,不过度校验
参考资料
mock使用参考:https://www.jianshu.com/p/77db26b4fb54
PowerMock简单实现原理
当某个测试方法被注解@PrepareForTest标注以后,在运行测试用例时,会创建一个新的org.
powermock.core.classloader.MockClassLoader实例,然后加载该测试用例使用到的类(系统类
除外)。
PowerMock会根据你的mock要求,去修改写在注解@PrepareForTest里的class文件(当前测试
类会自动加入注解中),以满足特殊的mock需求。例如:去除final方法的final标识,在静态方法
的最前面加入自己的虚拟实现等。
如果需要mock的是系统类的final方法和静态方法,PowerMock不会直接修改系统类的class文件,
而是修改调用系统类的class文件,以满足mock需求。
spring使用的runner一般是SpringJUnit4ClassRunner;当要使用powermockRuner的时候需要使
用注解.@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
jacoco可以通过远程监控的方式监控tomcat部署的项目;查看功能测试执行后的功能覆盖率情况;
|
|