BladeX 自动化测试工具开发系列 (一):自动化测试工具开发的的起因
自动化测试工具开发的的起因
那天晚上十点半,我点完第 26 个接口,页面弹回了登录页。token 过期了。前面点的全白点。我盯着屏幕看了足足5秒,把杯子里剩的凉茶喝完,从第 1 个重新点。26 条用例,一条一条点,一遍 40 分钟。dev、test、prod 三个环境,一个版本各跑一轮,需要两个多小时。这活儿我干了2个月了,点完了还要手写测试报告,有点想摔鼠标的冲动。
手酸不是事儿。真难受的是第二天早上开发问我:昨天那版比上一版,好了还是坏了。
我答不上来。我只有一个印象,好像有两条没过。哪两条?记不清。Excel 里记了一半,另一半在聊天记录里翻。至于"这次和上次比",从来没人答得上来,包括我。
所以我要做的东西,一开始就不只是"点得不累",而且要"点完了得留下点什么"。
我们的团队
老张:15年C#开发经验,Java早起1-2年开发经验
小刘:测试专业,是来实习的,第三周。
小李:2年Java开发工程师
我们的现状
人是会习惯的。点一遍 40 分钟,我就当是活动手指。真正让我坐不住的是一件小事:有个版本的发布接口,上一轮是通的,这一轮不通。开发问我什么时候开始不通的,我翻 Excel,翻聊天记录,最后只能说"上次跑还是好的"。"上次"是哪次?不知道。
那一刻我才明白,手工回归真正贵的东西是记录——它一个都不产生。你干得越多,忘得越多;忘了以后,只能重来。而且你永远说不清一件事:这次红了,是代码坏了,还是我点错了。
这事没法靠"再认真一点"解决。认真解决不了不可重复。
我算过一笔账(算着玩的):假设一周发两版,一轮两个多小时,一个月二十来个小时。一年多下来二百多个小时,全花在重复点同一批接口上。这二百个小时里我记住的东西,不超过十条。剩下的漏了,漏得还挺安心——反正明天还要再点一遍。
所以我决定让机器干。但这个决定下得特别慢,因为我先花了很长时间,去证明"现成的东西不行"。
我们的行动
既然要做自动化,最简单、最快的当然是使用现有的测试工具或开源的项目,我抽时间调研了现在常用的接口自动化测试的工具,准备给自己减减负(我也想按时下班,如果允许上班再摸会鱼)。
Postman。 上手最快,图形化,能跑 collection。问题出在环境一多:base_url、tenantId、账号、密码、几个固定 id,散在环境、集合、请求三层里。多环境就得复制多份 collection,改一个字段忘三处。
更要命的是造数——我得先往库里插一条活动草稿,再调发布接口。Postman 要在 pre-request script 里写 JS 去连数据库。写到一半我把窗口关了。
JMeter。 压测出身,断言靠一个个拖元件。我要断言"库里 activity_status 是 1",得挂 JDBC Request,再挂个 BeanShell 把结果掏出来比。技术上能做,但折腾半天出来的东西是个 jmx 文件,除了我没人看得懂。这玩意儿变不成我们项目的回归资产。
自己写 JUnit。 这条其实最接近答案。26 个方法,一个接口一个 @Test,跑起来还挺爽。问题是每接一个项目,重写一遍。第二个项目开工那天,我看着上一套代码,突然不想复制了。
三条路技术路线完全不同,都没有解决我的问题:它们都没把"项目差异"变成数据。 差异藏在 collection 文件里、藏在 jmx 里、藏在代码里。差异在哪儿,你就得去哪儿改。改完还得记住改过什么。这句话后来成了整个设计的地基:能变的都搬进表里,代码只留不变的。 11 张表全是这一句话的展开。
小刘
小刘是来实习的,测试专业,第三周。
那天他站在我旁边,手里是我手工回归用的那沓 A4 纸,正反面,上面全是勾。
小刘:「张工,这个能给我一份吗?」
我:「你要这个干嘛,这就是我自己打勾用的。」
小刘:「我想照着点一遍。点完我就知道这系统在干什么了。」
我把纸给他了。结果第二天他还回来,上面用红笔加了几行字,是他点的时候发现的:有两个接口的返回字段跟纸上的对不上。
我当时心里动了一下。这沓纸在我手里是消耗品,到他手里变成了资料。
后来他说想跟着做这个工具。我说这活儿不轻松,也没人给你记功。
小刘:「我又不是来记功的。」
行吧,那就跟着。他后来叫我师父。(这称呼我一开始不太习惯,现在听着挺顺耳。)
小李是另一回事。他是做 Java 开发的,二十七、八,业务熟,手上三个模块都能改。我跟他说要做个工具,他第一反应是"这活儿该三个人干"。
小李:「师父,你自己做,做到哪年?我给你把设计翻成能执行的东西,小刘跑命令收结果,你只管拍板。」
我:「你俩能坚持多久?」
小李:「起码这个版本没问题。」
分工就这么定的:我定方向、拍板、兜底;小李把文档翻成任务卡;小刘跑命令、收证据。当时只觉得是分活儿,干到后面才看出来,这三摊活儿要的东西完全不一样,一个要判断,一个要翻译,一个要较真。
那天下午我把需求写下来了,就一页纸,四条原则,用的都是我自己的话。先把话说前头:BladeX 是我们公司那套 Spring Boot 脚手架,权限、租户、字典、代码生成全都现成,项目都是在它上面二次开发。所以"只针对 BladeX"不是限制,是省事。
只针对 BladeX 快速开发框架,勿做成大而全,需做成小而实用。
可以集成第三方的测试工具。
能做成配置项的尽量做成配置项;项目地址、数据库、redis 等因项目而不同的信息都存储到数据库中,在软件界面中进行切换。
数据库使用 MySQL。
第四条现在看着有点好笑,数据库用什么也算原则?当时算。因为我要的不是"我机器上能跑",是"换台机器、换个人也能跑"。这条后来救了我:所有配置从第一天起就在库里,没有一行藏在我的 application.yml 里。
写完这四条,我顺手加了一句边界:只做接口层,不做被测系统的 UI 自动化。 UI 一改版,用例全废,这活儿一个人维护不动。当时小刘问了一句"那界面上的问题谁管",我说归人工。他哦了一声,没再问。这个"哦"我记到现在,因为它是我们第一次主动放弃一块地盘。
然后小刘翻了翻那页纸,翻到功能第 6 条,抬头问我:
小刘:「师父,这条最重要。」
我:「哪条?」
小刘:「'能看出什么原因导致的测试不通过'。因为报告是给开发看的。我拿一份只写着'失败'的报告过去,人家第一句肯定问我:是环境挂了,还是你用例写错了?我答不上来,第二次人家就不看了。」
我原来想的是"生成个 HTML,红的绿的,挺好看"。没想过这报告是要被人拿去质问的。
我没接话,在本子上写了三个字:分得清。
后来预检、归因、hint 那一整套东西,源头就是这句话。当时我以为自己在做"报告",其实是在做"证据"。
小李
写代码之前,卡在语言上。
师父是10年 C#,从 WebForm 写到 ASP.NET Core,Visual Studio 闭着眼能开。Java 写过两三年,看得懂,改得动,写起来处处别扭。
小李不理解。
小李:「师父,你写 C# 多快啊,为啥非要用 Java?」
我:「我快一周,然后花一天时间验证是因为两个体系同一方法的结果不同(比如加密、解密,踩着坑过来的)。」
小李:「差这么多?」
我:「差这么多。」
被测系统是 BladeX,Spring Boot。它返回的 JSON 怎么序列化、雪花 ID 怎么处理、登录体怎么 AES 加密,这些我都得在测试工具里重写一遍。重写完还得验证"我这版跟它那版是不是一回事"。这个验证成本,比学 Java 高得多。
界面
语言定完,定形态。三个候选:桌面程序、Web 平台、命令行。
桌面程序我其实最顺手,WPF 写过好几年,拖个界面出来不难。但它有个绕不过去的问题:发给谁。发给我自己,那跟命令行没差别;发给三个人,就是三个 exe、三次升级、三套配置,每加一个环境还得重发一遍。这工具的命门是"能天天跑",不是"能双击打开"。
小李主张 Web,理由很充分:人家 MeterSphere 就长那样,环境、用例、报告全在页面上点。
小李:「咱们也做个页面吧,环境切换在页面上选一下,多直观。」
我:「页面要多久?」
小李:「前端我来,两三天吧。」
我:「两三天是把页面画出来。登录呢?部署呢?每个环境部署一份还是共用一份?跑起来之后日志在哪儿看?」
小李:「……那就得两周起了。」
我给这笔账算了三遍,每次都是同一个结果:给一个人做的工具,最贵的成本是界面。
界面压根不只是前端。它意味着一个常驻服务、一个部署位置、一套"谁都能点"的权限边界,还有一堆"点错了怎么办"的兜底。这些成本在有人天天用的时候是值得的,在我们连一条用例都跑不通的时候,纯粹是给自己看的。
小刘关心的是另一件事:
小刘:「那我怎么跑?」
我:「一条命令。」
小刘:「就一条?」
我:「就一条。」
java -jar tpt.jar --project=antidoping --env=test --tag=smoke
小刘看了一眼说这个我会。我说会就行。
换环境也是同一条命令,就换一个参数:
java -jar tpt.jar --project=antidoping --env=dev --tag=smoke
java -jar tpt.jar --project=antidoping --env=test --tag=smoke
java -jar tpt.jar --project=antidoping --env=prod --tag=smoke
三行命令,三个环境,代码一行不动。
工具
设计要的是"全局视野 + 反复推翻自己",编码要的是"局部收敛 + 严格验收"。这两种能力对模型的要求是反的。 一个模型同时干,必然有一头塌掉。
于是分成两条流水线:WorkBuddy 那边出文档、做评审、拆任务卡;opencode 这边按卡写代码、按验收自检;我在中间复核门禁。
小李听到这儿有点不服气。
小李:「师父,这丢给 AI 不就行了?我看人家 demo,需求一丢,它自己拆任务、自己写、自己跑测试。」
我:「demo 里那个项目,有 26 个接口要回归吗?」
小李:「……没有,就一个待办清单。」
我:「待办清单没有租户、没有鉴权、没有 AES 加密的登录体、没有雪花 ID——就那种十九位的长整型主键,JsonPath 一不小心就给你解析成浮点数。它跑通了,说明它能写代码,不说明它能写我们这套代码。」
他没接话。过了一会儿又问:
小李:「那 AI 把设计写了,代码也写了,我们仨干啥?」
我:「你俩干的活比我多。」
小李:「啊?」
我:「小李你把文档翻成任务卡——一张卡得写清楚目标、依赖、实现要点、锁死的版本号,还有验收命令和期望输出。卡写糊了,AI 写出来的东西整个偏。小刘你负责跑和查:它说跑通了,你跑一遍;它说断言过了,你翻明细看是不是真过了。」
小李:「那我这活儿不就是翻译?」
我:「是翻译。而且是最容易翻错的那种翻译。」
举个具体的。计划里写"实现鉴权模块",那是提纲,不是任务卡。任务卡得写成:token 缓存 TTL 取 expires_in − 60s,响应里没有 expires_in 时读 default_token_ttl(默认 14400 秒);401 只重放一次;头名从 api_headers 模板渲染,不许硬编码 Blade-Auth。
这四条里漏任何一条,AI 都会给你一个"看起来能跑"的实现——它猜得挺合理,就是跟你说的不是一回事。
人只干三件事:拍板、复核、兜底。
拍板是把选择题做成决定,两个方案都行,选哪个、放弃什么。复核是要证据,不是"我改好了",是命令加输出。兜底是真环境试跑,机器不知道我们那套环境的脾气。
1900



被折叠的 条评论
为什么被折叠?



