从项目开发到云端架构 7
2.3.5 软件测试
2.3.5.1 测试步骤
测试在项目开发中占据重要的阶段。按照软件工程的要求,系统上线前需要进行如下的测试阶段:
单元测试:由模块开发者具体来实现,根据规范,service为对外暴露的接口,程序员需要保证自己提交的service模块所有的方法都是被测试覆盖的。
程序员创建junit模块,利用maven工程区分的4个目录,测试内容放置在test目录下,其中代码放置在test/java下,配置信息放置在test/resource,该目录下的代码在作maven install的时候,是不会被打包在jar中。
模块开发者起码为每个service方法提供1个test方法,在创建service模块时,相应的junit api就要出具,所谓测试先行。此时的test api里面运行为成功,方便程序员在作maven install 生成jar包时,不会报错;如果在某个阶段需要1个jar包,但servcie模块有异常,可以跳过测试来打包,指令:mvn install -Dmaven.test.skip=true
Servcie包junit为正常后,代码允许提交,提交前,先请更新代码,如果有代码冲突,先解决冲突再提交代码。
如果按照每个service的api写1个test api,测试代码覆盖率是很低的,因为service的api内部有if等条件分支情况,1个test api是无法覆盖更多的路径。这需要开发经理根据项目情况,以及sonari或maven内部插件来检查测试覆盖率,根据具体情况安排程序员写更多的测试api。(maven集成了cobertura-maven-plugin,在生成site即可展现结果;snoar有类似的插件)
集成测试
本地集成:也许本地没有第三方系统的test环境,需要进行模拟测试
现场集成:尽可能接第三方的test环境,达到系统真实可用
写虚拟api,模拟返回的数据和异常规范
有的测试insert到特定的表,就假设测试成功
缺少jar包,缺少配置文件和相关信息:提交相应文件,解决冲突
缺少表和数据:提交给唯一的人进行控制,统一加表加数据并纳入版本控制
接口不匹配:修改接口等,在提交
返回报异常,报空指针等:缺数据,缺表,需要更新代码后重新跟踪代码。
开发团队开发团队需要搭建2个必要的环境,开发环境和测试环境,2个环境做到物理隔离,这样在作测试的时候,缺少的表和必要的数据就能很快的发现,并由唯一的人来统一配置。作为运营团队,需要有个和正式上线的产品同版本同数据库的环境,这部分在运营篇章阐述,这里忽略。
开发是分层分模块,团队内部分人来协作的,所以当每个人提交各自的代码时候,单元测试能通过的模块在集成测试有可能失败,失败的原因有:
在集成测试分为本地集成和现场集成
压力测试
Web压测:之前没有loadrunner持久压测web的案例,无经验可循;高峰测试可采用loadrunner工具。
后台压测:在高峰测试的时候采用loadrunner的工具即可;在持久测试采用java控制台方式。
持久压测:在长时间的持续压力对系统考验,主要是检查内存泄漏情况。根据在美盛的测试经验,如果是后台持续测试,采用loadrunner,loadrunner自身会随着时间的推移而对被测试目标的压力减小,而达不到测试目的,所以建议采用是多线程的java控制台测试方式,压力持续均衡,建议持久测试在24小时以上才有意义。
高峰压测:找出系统的能支撑的并发高值,并不一定要找出系统最大值(崩溃值),并建议可以模拟互联网用户的使用场景,即请求具有波浪式,某个时间点具有高值,某个时间点是低值,波浪式驱动。这个在loadrunner有很好的支撑。
白盒测试使用jprofile:由程序员来使用,项目开发中可以忽略,主要用于组件级别的开发
黑盒测试采用loadrunner和java多线程控制台程序:由测试人员使用,如果需要java控制台,则由程序员来提供给测试人员。
压力测试是检测系统在模拟生产环境下的性能表现,是上线前的最后测试,主要检查内存泄漏,影响系统平稳运行的问题。
压力测试从使用方式分为2种类型:白盒测试和黑盒测试
压力测试从压测目的分为2种类型:持久压测和高峰压测
压力测试从压测方式分为2种类型:web压测和后台压测
2.3.5.2 测试方式
结合maven进行测试
管理者的角度看到测试,关心的是更高层面和整体的测试结果,为此测试环境提供了2种类型测试方法,每种方法都有若干测试工具,并可被maven和sonar分别集成。通过manve集成的测试环境,对于项目经理可能更加贴近,因为能出具整体的项目代码的测试报告;而通过snoar集成的测试环境,对于技术经理更加适用,因为能在浏览器中模拟出可视化界面,并提供程序员之间的代码review。
静态方法是指不运行被测程序本身,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性。包括:Checkstyle,PMD/CPD, Findbugs等工具。对需求规格说明书、软件设计说明书、源程序做结构分析、流程图分析、符号执行来找错。静态方法通过程序静态特性的分析,找出欠缺和可疑之处,例如不匹配的参数、不适当的循环嵌套和分支嵌套、不允许的递归、未使用过的变量、空指针的引用和可疑的计算等。静态测试结果可用于进一步的查错,并为测试用例选取提供指导。
动态方法就是通过运行软件来检验软件的动态行为和运行结果的正确性,包括:Cobertura, Clover,Surefire软件。目前,动态测试也是公司的测试工作的主要方式。
与sonar集成
Sonar 是一个用于代码质量管理的开放平台。通过插件机制,Sonar 可以集成不同的测试工具,代码分析工具,以及持续集成工具。
与持续集成工具(例如 Hudson/Jenkins 等)不同,Sonar 并不是简单地把不同的代码检查工具结果(例如FindBugs,PMD 等)直接显示在 Web 页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化,从而可以方便地对不同规模和种类的工程进行代码质量管理。
Sonar 为代码的质量管理提供了一个平台,对传统的代码静态检测如 PMD、FindBugs 等工具进行整合,可以说是目前最强大的代码质量管理工具之一。
在maven的pom.xml已经做好了和sonoar的集成,只要架构师和开发经理在项目的控制台里执行:mvn sonar:sonar,结果就会导入到sonar的平台。为项目review和代码质量改进提供坚实的依据。
2.3.5.3 测试平台
图23-03:测试框架架构
主要部件如下:
Jenkins:基于Java开发的一种持续集成工具,用于监控秩序重复的工作,包括持续的软件版本发布/测试项目和监控外部调用执行的工作。
Builder:项目构建工具,包括前端war构建和后端jar构建。这里采用的是Maven工具。Maven 包含一个生命周期,Maven 会有序执行一系列的步骤,从而完成特定任务的构建。
测试环境:是测试平台的核心,包括了脚本管理,压力模拟,测试规则等组成部分。其中web端测试环境,后端测试环境以及移动端测试环境由环境管理服务器(使用puppet语言)来创建,管理,销毁。具体来说:
脚本管理:分为前端脚本和后端脚本,前端脚本借助Selenium产生脚本,并均置于版本的控制之中。后端脚本结合junit单元测试,并产生测试结果。
测试规则:不同的环境测试和测试业务的需求有所差别,根据不同的测试目的设定不同的测试要求,更加灵活的支撑全网各类项目的差异化需求。
压力模拟:在功能测试完毕后,需要对待上线系统进行一次模拟多人并发访问的测试,其本质就是发起多条线程同时连接到待测应用,并纪录其结果。
环境配置管理:全网项目众多,各种服务和环境千差万别,需要有统一的环境配置,并能提供标准的环境的生命周期管理,提供通用的服务,比如tomcat,mysql等,并通过脚本能完成一些环境初始化工作,通过自动化部署,减少人工部署的繁琐和差错。
测试流程
外部系统或定时调度驱动jenkins发起一次测试任务;
Jenkins执行外部命令:为该测试生成测试环境,典型的为基于虚拟机的tomcat+mysql的环境。
Jenkins执行项目构建命令:maven从svn获取指定版本的代码软件,通过项目构建生成jar包和war包,并部署到之前生成的测试环境中。
测试环境包括了脚本管理模块,测试规则模块,压力测试模块等。
脚本管理根据测试特点,从测试规则中匹配规则,对脚本进行修正和优化。如果是web页面测试,此前没有录入脚本,需要在这里录入脚本;如果之前已有脚本且不需要修改,直接沿用已有脚本。
根据测试的要求,启动压力模拟,产生一定数量的线程,并对结果进行纪录和统计。
产生的结果保存,并反馈给统计报表服务器,供用户查阅。
如果测试合格,可以经由环境管理服务器去配置生产环境,并把当前版本软件部署到生产环境。
来源:timeson http://timeson.iteye.com/blog
矽控电子®分别获“科技型中小企业”、“江苏省民营科技企业”、“创新型中小企业”认定,核心团队拥有十余年的硬件正向研发,生产制程,测试手法,品质控制经验。尤其擅长嵌入式ARM平台的人工智能与工控物联网产品,以及瑞芯微(Rockchip)、海思、NXP、新唐等平台的机器视觉类AIoT模组开发,为您的产品从创意到落地、批量市场化助力。
公司可提供从硬件设计(原理开发及PCB Layout),Linux驱动开发,PCB制板,SMT及接插件焊接,产品测试,产品老化全流程外包服务,收费合理,品质可靠。
定制开发找矽控,品质可靠省费用
垂询电话:0510-83488567-1 业务邮箱:wxdianzi#foxmail.com (#更换为@)