如何评价一个项目的过程质量?是从代码的层面,还是从发现的bug来统计,或者是其他信息。如何有效记录并分析每个测试阶段(冒烟测试、系统测试等等)的问题以及反馈提测质量?
本文主要介绍ChinaCache的CDN架构如何做分层自动化测试,以及分层自动化测试的价值所在。阐述的内容主要覆盖CDN核心运营支撑系统的分层自动化测试,当然测试结果不是最终目的,而是要打通整个软件生命周期的全程软件测试流程。
ChinaCache在2005年发布的《CDN技术白皮书》中描述的CDN统架构,是一套实际的、运行良好的商用CDN系统,如图所示:
CCN(ChinaCache Nod)模块对应分发服务系统,是CDN的基本服务模块,由分布于各个城市、各个运营网络中的cache设备和辅助设备组成。
GAC(Global Access Controller)模块,对应负载均衡系统,主要采用了智能DNS解析方案,负责通过域名解析应答实现将用户请求调度到最优服务节点的目的。
NOC(Network Operating Center)模块对应网络管理系统,负责对全网进行7×24小时的监控和管理。NOC可以监控ChinaCache CDN中的链路状况、节点响应速度、设备运行状态,也可以监控到客户的源站运行状况等信息,一旦发现异常马上采取相应措施予以解决,是保障CDN服务安全可靠性的重要系统。蓝汛的NOC中设置了源站点监控功能,对客户源站进行可达性监控,从而减轻或者避免由于源站故障造成的服务中断。
OSS(Operating Support System)模块对应运营管理子系统,负责采集和汇总各个CCN的日志记录信息,然后由中央处理模块加以整理和分析,最后通过客户服务系统进行发布(Portal)。客户通过Portal可以访问OSS提供的查询频道的实时流量、流量分布、点击数量、访问日志等信息。
由于整个ChinaCacheCDN的架构过于复杂,因此带来了很多的痛点。
测试人员发现问题(例如无法执行程序、无法打开)的时候又被动、无奈反复打回给研发人员处理,这些问题实际在研发人员自测阶段就应当发现并且修复;如何高效地进行冒烟测试,而不是反反复复的手工测试和口口相传的提测呢?在这种需求下如果没有见效的流程,就会停留在反复折腾:
研发提测 ⟹ 测试发现不通过打回 ⟹ 研发修复继续提测 ⟹ 测试继续冒烟
这种一来一回的模式实在是消耗了大量宝贵的时间,本来测试时间已经被项目周期压缩的少之又少了,加上研发过程的质量不达标,反复占用测试周期中最后的宝贵时间来修复问题。如果把测试过程交给系统去评估质量和执行用例,设定由研发人员、测试人员认可的预设条件作为冒烟测试阶段,通过之后则相当于具备了正式提测条件,依照这样的流程,从而让研发人员、测试人员把重复的工作时间节省下来,更加专注去关注业务的实现。
在一些场景,例如重构需要回归测试,如果无法安排测试人员执行测试用例,研发人员只能等待,进度只能被延后;按照分层思想的构建,提供平台化的操作,研发人员完全可以自助让通过冒烟测试阶段的产品/项目,进入系统测试阶段,自助在测试平台配置功能回归测试用例,完成任务。
这种状况导致研发人员必须强依赖与测试人员构建冒烟阶段。在CDN架构中,如何及早介入冒烟测试,如何快速回归验证功能的有效性,从代码、服务等层面进行质量评估呢?这个可以通过分层测试架构来解决。
ChinaCache的CDN架构,其部分核心运营支撑系统如下图所示:
节点内资源调度平台,是基于高性能代理服务器Nginx和云存储系统构建的新一代CDN平台,旨在降低资源成本,提高用户体验。其最核心的特征就是系统分布式化,业务存储分离,提供分级存储功能等。
负责针对ChinaCache核心业务、支持系统、基础资源等进行配置管理、配置下发等操作。
一个简单场景:客户要修改域名解析配置,通过运维工程师在CMS后台修改之后,等待配置下发到节点服务器即可生效。
解析节点传过来的计费日志文件,生成各种维度的带宽数据进行实时入库(Redis)和持久化入库(Oracle),并提供API接口查询带宽数据。
一个简单场景:客户的带宽如何计算?每个频道的带宽是多少?带宽预测是多少?都可以通过计费系统得出结果。
以上提到的核心系统,有Web操作界面的、无Web操作界面的、有用Java编写的、也有用Python编写的,当然还有C、Lua编写的,核心运营支撑系统之间通过API接口进行数据交互。这些场景完全可以按照分层测试的思想来进行划分,Martin Fowler在博客中解释了TestPyramid,如下图所示:
借鉴此思想,对CDN核心运营支撑系统进行分层测试划分如下:
目标架构设计思想用一句话描述为:
实现代码、服务、界面分层自动化的整体架构目标,金字塔式一体化分层管理
目标架构demo:
其优势如下:
主要是指:持续构建服务(Jenkins)、静态代码分析服务(Sonar)、配置管理服务、(Svn|Git)、统一构建工具管理(Maven|Gradle),可以使用Docker来构建。
测试基石层,主要是指:Unit & Integration Test,这里以Java为示例,涉及到
《自动化单元测试相关概念和流程》,编程语言集中在Java、Python,其中Java使用的单元测试框架是Mockito,Python使用的单元测试框架是Nose,或许有人问为什么不用EasyMock呢?
这里给大家摘录一个表格《Mockito VS EasyMock》
Mockito | EasyMock |
---|---|
strict expectations | strict expectations |
non-strict expectations | strict expectations |
Mockito does not have any methods to change from record phase to replay phase | replay (mock)’ or ‘replayAll ()’ |
The Mockito APIs completely do not support implicit verifications | verifyAll()’ |
When call is made to non-void methods, Mockito points out a mock field or mock parameter that will generate cascading mocked instances | EasyMock does not generate cascading instances |
Mockito supports mocking multiple interfaces | EasyMock does not support mocking multiple interfaces |
Mockito supports mocking annotation types | EasyMock does not support mocking annotation types. EasyMock supports mocking enum types |
Mockito supports automatic insertion of mocks while performing tests | In EasyMock, mocks are not inserted automatically in tests |
在该层,通过自动化单元测试的持续构建,可以作为测试阶段的第一道门槛:冒烟测试。需要重点关注的环节——代码更新、代码编译、单元测试,这几个构建一旦失败,那就失去测试准入的原则了,这些问题必须要求研发人员修复直到构建成功为止,只有通过第一轮UnitTest冒烟测试之后,才有资格进入提测环节。
主要是指服务,计费服务、日志服务、HPCC缓存服务、HTTP API服务、无界面操作的后端系统,通过基于RobotFramework开源框架开发的测试工具覆盖计费、日志、HPCC等,API则使用《HTTP API测试平台》。
越往金字塔的上层,测试成本越高,特别是UI测试的投入需要非常慎重。如果页面元素频繁变动,不建议马上开展UI自动化测试,可以转变思想:长期稳定的功能,并且页面元素有清晰的定义,可以投入核心业务的UI自动化测试,例如Web可以使用Selenium框架、APP使用Appium框架,永远要记住:工具和框架只是辅助手段,带来多少的测试价值,关键在于评估ROI(投入产出比)。
为了最大程度发挥测试的价值,整个测试平台组花费了一个月研究讨论,其中最重要的一份草稿如下:
包括几个方面:如何实现分层测试的流程?如何持续构建、代码分析?如何将构建成功的包推送到自动化部署平台?如何做测试报告的聚合?图中有些隐约的答案,下面也会提到其中一些点。
或许读者会问:为什么要做这个平台?这不是用口号喊出来的,还是那句老话:
“叔本华说过一句话:由于频繁地重复,许多起初在我们看来重要的事情逐渐变得毫无价值。”
测试人员的价值不是在于重复劳动,而是把重复的工作交由机器完成,抽身出来把控整个研发、测试过程的关键点,不要被眼前的繁琐遮掩了测试的价值。
这里分析一下目标功能架构和目标技术架构(例如第一期重点实现HPCC自动化自助配置构建):
按照分层测试的思想,对代码层、服务层、界面层进行覆盖测试,其中还需要对设备进行监控(移动设备的监控、虚拟机测试环境的监控)。
技术架构是以之前的API测试平台为原型,沿用Python+Django,基础服务Jenkins、Sonar提供RESTful的API调用(如遇特殊业务场景,可以直接从Sonar数据库查询,再整合聚合报告展示),当然读者会问?怎么没有考虑分布式呢?目前架构设计轻量级就足够了,而且业务量并没有超出承载能力,水平扩展也是容易的,例如基础服务Jenkins支持Master/Slave。
如何发挥测试价值?可以从分层的测试范围来简述一下:
单元测试是第一道测试关卡,以前研发过程中,开发人员不关注代码质量,无单元测试投入,对代码规范无有效的审查、驱动改进的措施,使用平台之后:
服务层测试是第二道测试关卡,例如API测试,《HTTP API自动化测试从手工到平台的演变》,有详细讲解,
测试用例掌握在测试人员手里,研发人员无法运行,修复bug之后,只能等待测试人员验证,交付过程繁琐、效率低。
研发、测试协作同步,研发人员可以及早通过平台执行用例,验证功能可用性、正确性,测试人员可以释放部分劳动力,重点关注业务数据正确性;修复bug之后,研发人员无需等待,可以自助配置用例执行、查看结果,驱动过程质量的提升,同时做到夜间构建、邮件通知,工作时间review、bug fix。
在第二道关卡中,研发人员完成代码开发之后,可以使用平台进行API冒烟测试(流程上测试人员编写API自动化测试用例应当比研发人员完成代码编写时间早,这就是涉及到团队协作流程问题),勾选测试人员标记的冒烟测试用例,通过之后,可以进行深度的系统测试(关联系统测试用例)。在冒烟测试、系统测试环节,如果不通过,都会记录并且发送邮件通知研发人员,研发人员根据测试报告,排查存在问题的API,进行修复之后,再次提测,直到问题解决和通过为止。
并不是所有项目都有三层,不用生搬硬套,例如Portal有三层划分,HPCC缺没有UI层。Portal的UI层是如何做测试呢?在UnitTest、Service Test都通过之后,UI提测才更加有意义。
平台接受Portal的UI提测之后,会从代码仓库获取相应的UI自动化测试脚本(基于RobotFramework运行,使用selenium类库编写的测试用例),以及前面两层的项目代码,使用Jenkins与测试服务器进行交互,调用脚本部署Portal系统(当然,更加便捷的方式,可以把通过测试的发布包,推送给自动化运维平台完成部署工作,返回成功部署的服务器配置信息)。这里根据ChinaCache的业务场景,没必要划分严格的不通过准则,UI测试运行完毕,发送测试报告给相关利益者皆可,报告包括功能模块、测试用例,通过率等等。
以上是我在ChinaCache工作5年来最大、最长的自动化测试实践经历。平台化的东西,以前不敢想,是因为没有业务需求来驱动,以及如何说服老板来支持都是个大问题。
目前测试的种类繁多,导致需要人工验证的环节反复出现问题,当存在重复劳动的时候,就要琢磨有没有办法加速测试,提升效率呢?任何事情的演变以及进步,都是从小到大,积少成多;没有单元测试的推行,没有API自动化测试,没有UI自动化测试,平台也只是个摆设,每个层次都需要打好基础之后,接入平台只是流程的问题。
接下来要做什么呢?根据自己负责项目的业务复杂度,制定有效的自动化分层测试策略,说服你的老板,支持你!