持续集成与自动化测试

持续集成与自动化测试_第1张图片

持续集成与自动化测试

  1. 微服务化的基石——持续集成

某公司的主要业务是基础监控管理中台的建设。目前的项目还是采用单体模式,将所有功能打包在了一个包中,功能之间的耦合性高不容易进行拆分。未来的目标则是以微服务的架构来进行中台建设。

微服务架构(Microservice Architecture)通过将功能分解到各个离散的服务中以实现对解决方案的解耦,降低系统中的耦合性。将现有的系统划分成多个独立的系统并可以单独部署在自己的进程中,使得项目的部署更加灵活,也能根据用户去定制化系统功能。目前系统已经具有了一定的规模,之后系统的规模和复杂度也会越来越大,随着团队的扩大,每天需要修改的模块模块也会越多,为了保证代码的质量,就需要在每次提交代码时将所有模块进行集成和测试,反复的将拆分的模块重新组合并要求测试能够通过。如果要采用微服务架构,以目前的部署和运维大型集群的方式来说会十分的困难,我们需要一套持续集成来改变现状的状况。

2. 持续集成如何结合到开发、测试的工作中

在持续集成的工作流程中,当开发人员开始进行代码修改时,首先需要通过Git、SVN等方式来获取项目的最新代码副本,准备向代码库提交代码时,他们则必须要先对他们的代码进行更新,来反映出代码库中的最新更改。集成服务器往往也会提供Code revire、代码质量检测等功能,帮助开发人员通过Code review持续提高编程能力。在集成失败时,也可设置邮件、短信等告警及时对开发人员进行反馈。

在创建多个构建后,团队需要重新测试之前的版本中的可行功能。这个重新测试的流程以前被称为 “好代码(good code)”,现在称之为回归测试(regression testing)。它确保没有因为刚刚完成的变更而将错误引入或重新引入之前测试过的代码。利用 CI,可以将自动的回归测试编写为脚本,在每个构建结束时运行。这使得开发人员能够得到有关在在新构建中发现的错误的即时反馈。测试人员也无需因多次构建而需要反复的进行回归测试,节省大量的手工测试。

3. 持续集成与QA

功能测试是现在公司项目测试的主要部分,目前还是通过测试人员手工测试功能,并记录问题至 Gitlab 的 issue 中,然后待开发人员解决问题并合并代码后,测试人员再用 Jenkins 部署测试环境进行问题回归。整个测试流程主要依靠人工进行驱动。

在过去,这样的测试流程勉强可以进行下去,但是之后引入持续集成实践的话,每日的集成频率会大大增加,以目前的测试人员人力和测试周期易被挤压的实际因素,不但会增加测试人员的负担也会导致测试的质量下降。

所以CI在进入开发流程前,首先要将测试工作由过去的手工测试部分转化为高度自动化。从自动编译,自动部署到自动化运行单元测试,接口测试,UI测试最后进行集成测试和功能测试一整套流程。

以测试自动化金字塔来看,首先要进行的就是单元测试的推广。由于现实种种原因,单元测试并没有成为公司的工程文化之一,大部分的测试都是依赖测试人员来负责。今年公司未来微服务化目标明确并让大家都能理解CI的重要性,为了提前布局,测试这里先开始搭建自动化的框架,并且实现一部分的自动化测试,帮助之后开发人员也能更快的接受,更愿意去写UT做好准备。

持续集成与自动化测试_第2张图片

首先是单元测试部分进行技术选型。我们的项目是基于Python进行开发的,所以单元测试工具在Unittest和Pytest之间进行挑选就可以了。

Unittest作为较早接触过的单元测试工具,中在编写时会略显繁琐,相较于pytest来说,pytest的UT代码会更加的精简,由于pytest是基于Unittest实现的,所以Unittest的所有功能pytest都能够实现,并且还有Fixture功能可以在编写测试用例时更加的方便,只会Unittest的开发人员在稍微了解后也能很快上手,所以最后是选择使用pytest作为内部统一的单元测试工具。实际项目入手后,光是从断言来看pytest没有Unittest那么复杂的要求和格式要求,对于开发来说可以剩下很多的精力放在用例设计上。

持续集成与自动化测试_第3张图片

在单元测试选型的同时,也在进行接口自动化的选型也就是服务层的自动化测试工具。接口自动化的工具很多,所以主要挑选了代码型:Httprunner和Pytest,以及工具型的:Jenkins和postman。

工具型和代码型从自动化的结果和效率来说,两者差距都不大。工具型更加容易上手,对测试人员的代码素质要求不高,包括报告结果等都有完善的配套方案提供,缺点来说就是报告不如代码型来的好看,维护起来不方便,灵活度不高。代码型可以弥补工具型的缺点,但代价是对测试个人要求更高一些,初期编写效率不如postman。鉴于公司内部python大牛较多,到时候可以给予测试人员一定程度的技术支持,而工具型的测试报告过于难看,所以最后选择了代码型,而单元测试敲定pytest后,接口自动化也决定使用pytest作为自动化工具方案。

在项目中通过不同文件夹来管理单元自动化和接口自动化代码

持续集成与自动化测试_第4张图片

而且也继承了单元测试的精简风格,用更少的代码来实现效果

持续集成与自动化测试_第5张图片

UI自动化在去年实际已经提前有进行部署,主要是监控线上的前端页面和功能是否正常的运行。采用的是selenium作为自动化工具。作为老牌的自动化工具,selenium的功能十分齐全和强大,但是搞过UI自动化的都会比较清楚,在编写UI自动化脚本中最为痛苦的莫过于元素的定位,有时要重复定位反复调试来确定无法定位的原因,并且有时前端修改了页面后,自动化脚本也要一同进行维护,前面痛苦的过程也需要重新再经历一遍,而前端的变化远比后端接口要来的多,所以UI脚本的维护成本也要比接口自动化大的多。

所以今年,选择使用Cypress来代替selenium。相较于selenium,Cypress一大特色就是有可视化的窗口,并且可以统计每条case实际执行时间非常的便利。同样可以在用例出错时自动截图也可以生成测试结果报告,遇到客户端加载较慢情况时也不需要再手动加sleep()来避免脚本出错,维护起来也更加直观和方便,获得了开发和测试的一致认可,环境配置上Cypress也更加的方便。

持续集成与自动化测试_第6张图片

在代码这一块,Cypress和selenium不同点在于使用的是JS,在实际测试用例的编写上,Cypress也同样有代码更精简已经断言方式更加方便的优点,代码更加好懂,减少了后期脚本维护的成本。

持续集成与自动化测试_第7张图片

不足点是由于JS的特性,无法在测试完成或者出错时,自动将报告或错误邮件自动发送邮箱,需要python脚本主动帮助无法独立完成发送邮件任务。并且Cypress只能测试当前tab页,无法切换网页的句柄。部分涉及跳转页面的测试用例需要变成两条case来执行。

但是瑕不掩瑜,Cypress的易维护,易编写的点还是要比selenium要来得好。

持续集成与自动化测试_第8张图片

对于集成的频率来说,并没有一个明确的定义,往往是根据不同项目的实际情况来进行。根据Martin Fowler 的观点,项目 bug 的增加和时间并不是线性增长的关系,而是和时间的平方成正比,两次集成间隔时间越长,bug 增加的数量越超过你的预期,解决 bug 付出的工作量也越大,而你越觉得付出的工作量越大,你就越想推迟到以后去集成,企图到最后一次性解决问题,结果 bug 产生的就更多,导致下一次集成的工作量更大,你越感觉到集成的痛苦,就越将集成的时间推后,最后形成恶性循环。当其他的开发人员将自己更改后的代码提交至代码库时,副本代码将逐渐停止反映代码库中的代码,代码的分支保持检出时间越长,则当开发人员重新集成至主线时,多个集成冲突和故障的风险也会变得越大。频繁的集成和及时的反馈可以让问题更早的暴露出来,并使得团队更积极的面对问题,而不是将问题放到了最后去进行解决,如果持续集成能正确的执行,那频繁的集成不会成为负担而是为团队节省了大量的时间,使得交付时间可以提早摆上日程。

4. 公司CI/CD实现规划

在来年新规划中,公司还计划将涉及更多的领域去发展,其中包含了toc和tob的业务。现在存在着的现象是多名开发人员都需要在同一套环境中进行测试,经常要在部署自己模块时去技术组中询问下是否有人正在使用环境,如果发生冲突还需要等到晚上才能进行自己模块的测试这样就造成了时间上的浪费。随着人员和项目的逐渐扩张,开发之间难免会有互相踩踏的事故发生,其中还包括了机器学习这些运行测试成本较高的业务,往往要占用测试环境非常久的时间。而项目数量的增加,又会导致测试环境数量变多,环境从单节点走向了集群,前端时间为了测试新版本的系统的功能还需要运维人员去手工调度新的环境来搭建测试环境,一搭就是一个下午的时间过去了。再这样的背景条件下,为了能够满足测试和开发对有多套测试环境的需求与解决运维人员搭建环境和调度资源更加自动化,需要一套全新的CICD流程。

经过运维人员的讨论和实践,最终决定使用Kubernetes+Docker+Gitlab来解决现在这些问题,大致的流程模型如下图

持续集成与自动化测试_第9张图片

 

Kubernetes天生就十分适合解决微服务架构中复杂的应用关系以及对容器进行编排,对我们公司未来要建设微服务架构进行容器化这一目标来说无疑是最好的选择。Kubernetes在去年已经在公司其中一个项目组内开始搭建使用,用于提高服务器集群的高可用和均衡负载能力,同时为了之后将公司内部项目容器化的目标打下坚实的基础。

Kubernetes可以帮助改变过去的运维方式,通过Kubernetes可以轻松的的实现水平扩容、蓝绿部署等过去复杂的运维操作。比如直接使用YAML文件定义服务之间的拓扑结构和状态。通过简单易懂的声明方式,舍去了命令式的方式进行开发,减少了开发人员的工作。

持续集成与自动化测试_第10张图片

5. 总结

当Kubernetes和Docker搭建完成后,再配合我们现有的Gitlab和 OpenStack云计算管理工具后,我们的新CI流程就算初步完成了,流程图如下:

持续集成与自动化测试_第11张图片

1.开发人员本地通过测试后,将代码提交至Gitlab

2.通过Webhook插件触发Jenkins进行自动构建,Jenkins将代码打成Docker镜像。

3.在K8s-master上执行RC的创建,进而创建Pod,根据该镜像启动容器

通过新规划的服务流程,开发人员可以通过OpenStack来根据自己的需求去指定自己想要的服务器环境,也可以通过复制定制好的模板来选择自己想要的镜像环境,在效率上省去了等待运维部署的时间。在过去由于要在RC部署不同项目不同版本的项目,导致不同项目的开发人员在其它项目被部署在RC环境后,只能等待其测试结束后才能去部署自己的项目,现在可以做到一人一套RC环境,开发人员无需在意其他开发人员的部署安排。

和过去相比,新的规划将过去大部分的手工过程全部进行了自动化,节省了大量时间,针对不同项目不同工具的问题无需运维人员重新进行配置,能够保持各个项目自身的工具使用的同时,对于公共的仓库等工具的使用进行了统一。新的服务器架构搭建后能将闲置的资源都能进行有效的管理,并且为之后的服务容器化做好了前置准备。

相比过去的CI/CD流程来说,从提交代码到部署置RC环境需要30分钟左右的时间,新的流程下只需要一分钟就可以将后端部署至镜像环境。在需求紧急的时候我们团队开发一天可能要进行几十次的代码提交,通过新的集成流程,能为团队节省大量的时间。资源利用率方面,运维人员可以对服务资源达到100%的管控,避免了资源的浪费,并提升了部署的效率和时间。

“积硅步,至千里;积小流,成江海”。持续的集成和持续的测试,从单元测试到最后的验收测试,每个环节都将问题一一击破,从而一点点把问题从系统中排除。持续集成本身只是一种工具,只有各方的配合,持续集成才会有它的意义,才能更好的让软件问题被发现并解决。


绵薄之力

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走

这些资料,对于想进阶【自动化测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。希望对大家有所帮助....

你可能感兴趣的:(软件测试,技术分享,自动化测试,ci,自动化测试,测试工程师,软件测试)