当前位置:首页 > 杂谈 > 正文内容

城市创新月|SAP 南京研究院:一个软件架构师对测试的思考(sap成都研发中心地址)

2023-07-27 04:38:00TONY杂谈72

秉承“创新在中国,为中国,为全球”的创新战略

SAP 中国研究院不断突破、锐意创新

研发团队的每一员也在主动创新

在实践中感悟,在创新中成长

今日,SAP 中国研究院·城市创新月南京团队 Yu Qian 将从软件研发人员的角度

分享他作为一个软件架构师对测试的思考

我是一名来自 SAP MEcS (Midmarket & Ecosystem Success)部门,在自动化测试团队工作的软件架构师。今天我将谈谈对软件测试的理解和思考。

文中所有测试都指脚本执行的自动化测试。内容不代表任何组织机构,只是我的个人观点。

01

单元测试

单元测试的优势非常明显,它和业务代码在一个工程中平行放置,使用同一种开发语言,对开发来说在 IDE 中查看修改单元测试非常轻松自然,没有额外的技术壁垒。一般来说,单元测试执行并不需要复杂的配置和环境准备,执行速度也超级快,修改代码后可以立即执行马上获得反馈,不需要多少等待时间。这些优势对于开发效率至关重要。单元测试的缺点同样非常明显。单元测试的粒度非常细,一般来说,一个单元测试用例只会测试一个类中的一个函数的一种场景,开发单元测试的工作量和被测函数的外部依赖的数量强相关。对于算法类的函数,因为高度内聚,函数本身有复杂的逻辑,而外部依赖往往不多,单元测试的价值可谓非常巨大。但低内聚、强外部依赖的函数比如 CRUD 类的业务代码,则使单元测试能发挥的价值大打折扣。单元测试因为粒度细且位置过于底层,也是重构影响的重灾区。有很多并不影响对外功能的重构,被调整的功能本身的单元测试代码需要修复,还会造成相关的其它单元测试的 mock 数据也要一起跟着调整,工作量巨大,还经常会遗漏造成相关的单元测试失效。

在我经历的各种软件项目中,也看到了各种方法来解决这些问题。比如有的项目单元测试连数据库执行,这基本解决了单元测试对 CRUD 代码毫无价值的问题。但单元测试的执行受到很大影响,需要预先配置和环境准备才能正确执行。测试的价值和它执行的容易程度强相关,任何一个测试,如果不能通过一条极为简单的命令(mvn test 或 npm test 这种简单法)立即执行,且无需任何配置和额外准备,那它的价值最多只能发挥一半。此时至少有一半的开发会放弃本地执行测试,而是代码写完后,依赖 CI/CD 来执行。这使得问题发现和定位的周期显著加长,会浪费大量的宝贵人力成本。也有不少项目尝试在连数据库和执行效率间寻找平衡,通过在本地临时启动内存数据库(如 HyperSQL DB)或者文件数据库(如 SQLite)来进行单元测试,以达到既不需要额外的配置和环境准备,也可以测试 CRUD 代码的效果。但是内存/文件数据库本身并不具备大型数据库的完整功能,在开发过程中经常会碰到适配的问题,比如为目标数据库编写的 SQL 语句不能在内存数据库上执行。即使使用对象存储框架(如Hibernate,EclipseLink等)来避免直接写 SQL 造成的语法兼容问题,往往也只能解决最基本的场景,对于复杂的查询在内存数据库和大型数据库上的结果有差别甚至不支持也是很常见的。而且不同数据库的数据预置脚本往往也不能通用,就需要为单元测试额外写很多 SQL 文件来预置数据。因此不同方法的效果很大程度上取决于项目自身的情况,难以一概而论。单元测试毫无疑问有它独特的价值,但是也不应对其寄予超出能力的期望。对于高内聚低耦合,不会频繁改动的底层代码,比如任务调度算法,单元测试不光要写,还要仔细写,全面覆盖。但是对于 CRUD 类的代码,写单元测试并没有太大意义,反而会浪费宝贵的开发资源。说到底单元测试离代码太近,离需求太远。因此结合项目实际,有选择地写单元测试是比较合适的方法。

02

集成测试/ 服务测试

集成测试的定义很容易让人疑惑,我认为本质上即是把(通过单元测试验收的)各个函数集成在一起测试。在传统软件研发过程中,集成测试往往是以一个相对独立的功能模块为单位进行的。比如开发一个电脑上的音乐播放软件,可以对播放列表模块进行集成测试,也可以对歌词显示模块进行集成测试,这些通过集成测试的模块最后则是合在一起进行更高一级的端到端测试。近些年微服务的流行使得单个服务的体量显著降低,这使得集成测试的粒度划分有了变化。在微服务里通常在单元测试之后,下一层就是以一个服务为单位进行集成测试。测试时服务会连接真实的数据库等维持自身运行必要的外部组件,但对于其它通过远程接口依赖的服务,则通过 mock 的方式进行处理。测试脚本通过调用服务接口的方式,以(使用服务的)用户视角从外部对服务进行测试。因此这种测试也经常被叫做服务测试。

集成测试的优势在于它处在一个非常合理的位置上——一个服务/模块的外部接口是应该保持稳定,避免频繁变化的,内部的代码优化重构不应该影响外部接口和功能,此时测试用例不应该有变化。而当需求变化的时候,模块的外部接口也会发生变化,此时测试用例也应该跟着变化。当然需求的变化不止来自客户的功能性需求,也可能来自项目内外的非功能性需求。一个跟着需求走,同时又不关心服务内部代码变化的测试,这简直是所有重构行为最梦寐以求的东西。因此如果一个服务有覆盖率高且质量良好的集成测试用例,内部的重构就可以放开手脚进行。对于一个长期持续且频繁增加需求的软件项目来说,能持续且随时进行重构,对维持代码质量,避免架构腐朽的意义极其重大。集成测试是以用户视角,从外部对服务进行测试,因此它可以覆盖更为完整的业务流程。单元测试因为粒度过细,比较容易出现单个测试用例跑起来都正常,但是服务运行起来调接口却出问题的情况。而集成测试则可以很大程度上避免这种问题。同时因为连接真实的数据库,对 CRUD 业务逻辑的测试也是非常准确的。可以说通过了集成测试的服务起码已经具备了基本的可用性,是比较让人有信心的。集成测试的问题首先是场景覆盖不容易做到非常全面。很多时候因为内部逻辑的复杂性,想从外部接口覆盖到所有的内部代码是基本不可能的,或者就算可能,也需要写数量巨大的测试用例并且执行太长时间而变得不划算。其次集成测试同样大量使用了 mock,因此集成测试的质量也很大程度上依赖 mock 数据的质量。并且生成 mock 数据也是件非常费时费力的事情,对于已有的接口,可以到测试环境上调对应服务来获取样本;而还在开发中的接口有时候不得不根据需求先编一个出来。另外有时候依赖服务的接口有变化,可能并不会及时更新到相关的团队,也会造成集成测试使用老的 mock 数据来测试新的功能。另外集成测试相对单元测试,往往需要更长的执行时间,在本地执行也更不容易或者需要更多的配置或者环境准备工作。为了解决集成测试在 mock 数据上的问题,有的项目会选择将服务连接到测试环境上真实的其它服务来进行集成测试。这解决了一些问题,但也会带来新的问题。比如测试环境往往并不是稳定的,一旦有一个服务出了问题,就会影响很多团队执行测试。另外测试环境上的服务可能并没有实现新需求中的接口或者字段,造成联调无法进行。而且如果你需要对方服务上有特定的数据,如何准备这些数据也是个问题。最后如果很多团队连到同一个测试环境上,也容易出现测试数据互相干扰的情况。这两种测试方式如何选择,需要结合项目的具体情况来考虑,并没有统一的标准。

总体来说集成测试所解决的问题和带来的价值都是极其巨大的。特别是对于微服务架构下的服务测试,意义尤其明显。以至于有人提出在服务化的云产品中,软件测试的金字塔模型已经不再适用,而应当使用蜂巢模型——缩减最下方的单元测试数量,将重点放在中间的集成测试上。我也比较认同,同时我还认为,集成测试同样应该很容易运行,最好能够像单元测试一样容易。集成测试的代码一般和业务代码放在同一个工程中,这本身为开发人员执行集成测试带来很大的方便。对于数据库的依赖,可以要求开发人员在本地安装数据库实例,使用同样的端口和管理员账号。集成测试启动时自动连到本地数据库,创建 schema 并初始化预置数据进行测试。如果测试出现问题,开发也可以在本地检查数据库表,方便问题的定位。对于集成测试依赖的外部服务,也应当自动启动 mock,不应有手动操作。开发人员只需要一次性的环境准备,以后就可以很简单的在本地执行集成测试。测试能够发挥最大价值的地方永远是在最前方。

03

系统测试

系统测试也经常被叫做端到端(E2E)测试,就是把所有服务都按照生产环境的标准部署完成,对系统进行全面的测试。这种测试很大程度上是从最终用户的视角出发的,因此它可以从最终用户的视角发现问题。系统测试的质量也基本反映了最终用户在使用这个产品时的下限——一个系统测试结果很糟糕的产品,用户使用起来感觉必然是不友好的。

在我经历的不少传统软件项目中,这一步都是手工进行的。一方面对于传统软件研发来说,因为发布周期很长,手工测试的成本也不是不能接受。另一方面,手工测试确实会发现更多问题。对于纯接口的功能,人工测试在这方面并没有太多优越性。但对基于浏览器的前端 E2E 测试来说,自动化测试的挑战就变得非常明显。首先页面前端测试基本是通过 Selenium 对浏览器页面的元素进行操作的,其中非常关键的一步就是如何找到页面上的元素。很多页面前端,输入框、按钮等元素并没有一个稳定的唯一 ID,甚至于每次打开同一个页面的同一个按钮,它的 ID 都会不一样。这使得自动化脚本只能通过 xpath 等其它方式来定位页面元素,页面如果有调整,往往就会影响到自动化脚本里的 xpath,造成大量测试用例失效。对于需求频繁变更,且页面频繁变化的产品,测试开发的时间日常要大量花在修正这种错误上。这使得维护自动化测试脚本的工作量居高不下,执行准确率也大打折扣。其次这种测试方式只能验证页面有这个元素,而且元素的状态是正确并且可以操作的,但是并不能验证元素的视觉是否正常。简单来说就算前端人员犯错改坏了页面样式,导致页面显示变得一塌糊涂,但自动化测试脚本仍然可能正常执行通过。因此人工视觉检查这一步是无论如何都无法省掉的。另外自动化测试对于正在还发中,还不存在的页面基本无能为力。如果看不到具体页面,测试开发人员就无法编写测试脚本。这使得自动化测试的时效性有着严重的滞后。最后自动化测试和人工测试一样,都需要一个完整的环境才能执行。对于传统软件研发过程来说,这个环境并不是一直存在的,一般要到项目发布的后期,开发阶段基本结束,才能部署环境进行测试。这也使得自动化测试难以发挥其规模优势。

但是云服务化、微服务架构以及灰度发布等相关技术的流行,使得自动化测试能更好地发挥它的价值,也变得越来越流行了。在微服务架构下,发布周期变得更为灵活,很多产品并不是等半年升级一次大版本,而是做完一个功能就把相关服务进行升级,使功能尽快上线。快速发布的新功能使得产品能够快速试错,获得市场上的领先,但同时也给软件测试带来巨大的挑战——微服务之间的联系错综复杂,每个服务的升级都会对很多功能产生潜在影响,需要频繁甚至一直执行全量的测试用例来保证产品质量,这使得人工测试的成本变得完全无法接受。另一方面,云产品一直在线,巨大的体量也使得部署一个全功能的测试环境变得不太实际。很多产品采取的是通过在生产环境中进行灰度发布——先将某个服务的少部分实例替换成新版本,通过配置使得正常功能执行时仍然走老版本服务,只有新功能测试的请求经过新版本服务,来进行测试。这些变化显著强化了自动化测试的优点。测试团队可以一直在生产环境上打磨自动化测试脚本,获得高质量的测试结果。粒度更小的新功能上线规划,使得自动化测试不必应付页面大量变更的大版本升级,每次只需要较少的脚本更新,更容易赶上新功能上线的计划。而自动化测试执行时不需要人工成本,效率高且可以一直循环执行,加机器就可以缩短执行时间的优势就变得非常吸引人。在不少云产品里,已经基本全自动化测试或自动化测试为主手工测试为辅了。

自动化测试在软件发布流程中也具有非常重要的位置,测试报表是否容易阅读并被相关人员理解,很重要。使用 cucumber 并以行为驱动 BDD 为核心开展的自动化测试,因为从需求、功能开发、测试开发到报表都是围绕人类可读的产品行为描述脚本进行的,具备天然的优势。如果自动化测试能接入公司自身的 IT 流程,将报表自动上传到如 SAP Cumulus 等系统中,在易用性上的优势也是非常明显的。对于测试开发人员来说,更关注自动化测试脚本开发调试是否容易、开发环境和工具是否齐全、在 CI/CD 执行时能否实时预览执行过程的画面、查看执行日志、执行结束后能否进行视频回放、报表是否简单易读、出问题时报表中是否包含了关键信息等方面。能够集成 JIRA 等工具自动创建 Bug 报告,也能节省测试开发人员大量的时间。

欢迎进一步了解来自 MEcS 自动化测试团队的自动化测试解决方案 STAF 和 QFrog:

https://github.wdf.sap.corp/pages/CESQ/Documentation/

欢迎持续关注 SAP 中国研究院官方微信并积极与我们互动,我们期待聆听您的声音。如果您想进一步了解或创新合作,可以通过下方邮箱联系我们:

window.saplabschina@sap.com

往期回顾

点击图片详细了解

“城市创新月|SAP 南京研究院:一个软件架构师对测试的思考(sap成都研发中心地址)” 的相关文章

提示!2022年一级建造师考试补考准考证打印入口已开通

提示!2022年一级建造师考试补考准考证打印入口已开通

原标题:提示!2022年一级建造师考试补考准考证打印入口已开通 2022年一级建造师补考准考证打印时间为3月17日起,打印官网为中国人事考试网。各地准考证打印持续时间不同,具体打印时间以各地补考公告中公布的时间为准(2022年各省一建补考准考证打印时间)。 2022年一级...

用户登录的详细流程

用户登录的详细流程

** ## 用户登录的详细流程 ** ** ## 1.流程概述 ** (1)首先在进行用户登录的时候,要进行一些必要的准备工作。 比如说要对用户登录表进行设计。 一般是userId,userName,phone,passwor...

视频号内测运费险 或将于 5 月正式面市 智己汽车联席CEO刘涛:第三款车和第四款车分别对标特斯拉Model Y、Model 3

视频号内测运费险 或将于 5 月正式面市 智己汽车联席CEO刘涛:第三款车和第四款车分别对标特斯拉Model Y、Model 3

【亿邦原创】亿邦动力独家消息,微信视频号正在灰度测试运费险,有商家称测试已持续近三个月。此前,有商家告诉亿邦动力,视频号运费险可能会在今年 5 月正式上线。 运费险是电商重要基建之一,几乎是平台标配服务。2020 年,抖音就上线抖店运费险服务,此后不断推出补贴计划。2021 年,快...

扎心了!PubMed 正式上线了新版本,却被 Science 无情吐槽(附新版超详教程)

扎心了!PubMed 正式上线了新版本,却被 Science 无情吐槽(附新版超详教程)

PubMed 是广大科研狗们一个常用和十分熟悉的网上免费生物医学数据库,最近他们上线了一个你从来没用过的船新版本。 然而 Science 却发表了一篇题为 They redesigned PubMed, a beloved website. It has...

楼市进入复苏通道,一二线城市2月房价环比均上涨

楼市进入复苏通道,一二线城市2月房价环比均上涨

界面新闻记者 | 杨冰柯 界面新闻编辑 | 无论是房价还是销售数据,热点城市楼市均迎来小阳春。 3月16日,国家统计局发布2月70个大中城市商品住宅销售价格指数。2月份一、二、三线新房价格环比全部上涨;二手房环比上,一线和二线城市房价环比上涨,三线城市房价环比持平...

3月房价环比全线上涨!超9成城市新房价格环比上涨,武汉领涨70城

3月房价环比全线上涨!超9成城市新房价格环比上涨,武汉领涨70城

每经记者 包晶晶    每经编辑 魏文艺     新房、二手房价格环比全线上涨。 4月15日上午,国家统计局公布的《2023年3月份商品住宅销售价格变动情况》显示,70城房价环比全线上涨,其...