聊聊我在网易做游戏测试工具的一些实战经验
早上八点钟,窗外的天刚蒙蒙亮,我已经坐在了家里的书桌前。手边是一杯刚冲好的美式,屏幕上是昨天跑了一半的K8s集群监控面板。远程办公的日子过了大半年了,说实话,我挺享受这种状态的——不用挤地铁,不用跟同事抢会议室,穿着拖鞋就能开晨会。
我在网易游戏做服务端开发已经三年了,参与过几款上线的游戏项目,从最初的手忙脚乱到现在算是能独当一面。今天想跟大家聊聊我们团队在测试工具这块做的一些实践,尤其是最近半年引入AI之后的一些变化。
被测试同学逼出来的觉悟
先说个背景。去年年底我们有一款卡牌手游准备上线,项目代号就不提了。当时离公测只剩不到两个月,服务端这边的接口已经有三百多个了。测试团队的小王有一天在周会上直接开炮:"你们服务端每次提测,接口文档跟实际行为对不上的情况太多了,我这边写自动化用例的效率特别低。"
说实话,这话没毛病。我们之前的接口文档用的是Swagger自动生成的,但说实话,很多接口的业务逻辑描述写得跟天书一样,测试同学根本看不懂。再加上游戏业务本身就很复杂,什么"抽卡保底机制"、"公会战积分计算",光看接口文档根本猜不到实际行为。
当时我们组的测试覆盖率大概在60%左右,每次版本更新都要靠测试同学手动点点点,效率很低。而且游戏有个特点,就是运营活动特别多,几乎每周都要上新活动,每次新活动都会带来一批新接口或者接口变更,测试的压力可想而知。
我当时就想,能不能搞一套工具,让测试用例的生成和维护变得更高效一点?
第一版:传统自动化测试的挣扎
最开始我们的思路很传统,就是搞接口自动化测试。用的是Python + pytest这套组合,配合Jenkins做CI/CD。
说实话,这套方案本身没啥问题,业界用得很成熟了。但落到游戏业务上,就遇到了几个很头疼的问题:
第一,测试数据的构造太麻烦。 游戏不像电商,你测个下单接口,随便造个用户、随便加个商品就行了。游戏里你要测一个"公会Boss战"的接口,你得先有公会、有成员、有Boss血量、有各种buff状态……构造一套完整的测试数据,有时候比写测试用例本身还费劲。
第二,用例维护成本太高。 运营活动一更新,接口参数变了,或者返回值多了几个字段,之前写好的几十条用例就全挂了。测试同学每周光修用例就要花掉一两天时间。
第三,边界条件覆盖不全。 人工写用例,难免会有遗漏。之前线上出过一次事故,就是一个充值接口的金额参数没做负数校验,结果被玩家薅了羊毛。事后复盘才发现,测试用例里压根没覆盖这种情况。
那段时间,测试团队怨声载道,我们服务端也被骂得够呛。我作为组里对工具链比较感兴趣的人,就被leader拉去牵头搞测试工具的优化。
当时我第一反应是:这活儿不好干啊。
转折点:AI应用带来的新思路
今年年初,ChatGPT火得一塌糊涂,我们公司内部也开始讨论怎么把AI能力落地到实际业务中。我當時就在想,AI能不能帮我们解决测试用例生成的问题?
说实话,一开始我是抱着试试看的心态。我拿了我们一个公会系统的接口文档,丢给GPT-4,让它帮我生成测试用例。结果出来的东西让我眼前一亮——它不仅生成了正常场景的用例,还自动补充了很多边界条件,比如"公会人数为0时发起公会战"、"成员等级不满足要求时加入公会"这些我之前压根没想到的case。
当然,直接生成的用例不能直接用,里面有些参数格式不对,有些业务逻辑理解有偏差。但作为一个起点,已经比我预期的好太多了。
于是我就开始琢磨,能不能搭一个pipeline,把AI能力集成到我们的测试流程里?
我们的测试工具架构
先说一下整体的架构思路。我们最终搞出来的方案,核心是三个模块:
| 模块 | 功能 | 技术栈 |
|---|---|---|
| 接口解析器 | 解析Swagger文档,提取接口信息 | Python + FastAPI |
| AI用例生成器 | 基于接口信息生成测试用例 | GPT-4 API |
| 用例执行引擎 | 执行测试用例并生成报告 | pytest + Allure |
接口解析器
这个模块相对简单,就是把Swagger JSON解析成结构化的数据。但这里有个坑——我们的Swagger文档质量参差不齐,有些接口的description写得含糊不清,有些参数没有标注是否必填。
为了解决这个问题,我写了一套校验规则,对Swagger文档做预处理。比如检查每个接口是否都有description,检查参数类型是否合法,检查是否有遗漏的必填字段标注。如果发现问题,会自动生成一份报告反馈给开发同学,让他们补全文档。
这步虽然增加了开发同学的一点工作量,但从长远来看是值得的。文档质量上去了,后面AI生成的用例质量也会跟着上去。
class SwaggerValidator:
def __init__(self, swagger_json):
self.swagger = swagger_json
self.issues = []
def validate(self):
for path, methods in self.swagger.get('paths', {}).items():
for method, detail in methods.items():
# 检查description
if not detail.get('description'):
self.issues.append(
f"接口 {method.upper()} {path} 缺少description"
)
# 检查参数定义
for param in detail.get('parameters', []):
if not param.get('type'):
self.issues.append(
f"参数 {param.get('name')} 缺少type定义"
)
return self.issues
AI用例生成器
这是整个方案的核心。我设计了一套prompt模板,把接口信息、业务上下文、历史bug记录这些内容组合起来,喂给GPT-4。
这里有个关键的设计决策:prompt怎么写?
一开始我写得很简单,就是"请根据以下接口信息生成测试用例"。结果生成的用例太泛了,很多都是"测试正常请求"、"测试异常请求"这种废话。
后来我调整了策略,把prompt拆成了几个部分:
- 角色设定:告诉AI它是一个资深的游戏测试工程师
- 业务上下文:把相关的业务规则、数值配置等信息喂进去
- 历史bug参考:把过去同类接口出过的bug列出来,让AI知道要重点关注哪些场景
- 输出格式约束:明确要求输出pytest格式的代码,包含具体的参数值
调整之后,生成质量有了质的飞跃。举个例子,对于一个"领取每日奖励"的接口,AI不仅生成了"正常领取"、"重复领取"这些基础case,还生成了"跨天领取时奖励重置"、"VIP等级变化后奖励档位变化"、"并发领取时的幂等性"这些比较深入的case。
当然,AI生成的代码不能直接跑,还需要做后处理。比如它有时候会把参数名搞错,有时候会编造一些不存在的枚举值。我们写了一套校验和修正的逻辑,对生成的代码做自动检查。
PROMPT_TEMPLATE = """
你是一名资深游戏测试工程师,精通Python和pytest框架。
请根据以下接口信息生成完整的测试用例代码。
## 业务上下文
{business_context}
## 接口信息
{api_info}
## 历史Bug参考
{bug_history}
## 要求
1. 覆盖正常场景、异常场景、边界条件
2. 每个用例都要有明确的assert断言
3. 使用pytest格式,包含fixture
4. 测试数据要具体,不要用占位符
5. 对于涉及时间的场景,要考虑跨天、跨周等情况
"""
用例执行引擎
这部分我们复用了之前的pytest + Allure方案,改动不大。主要是加了一个用例管理的功能——AI生成的用例会先进入一个"待审核"状态,测试同学review之后才会进入执行队列。
这个设计很重要。AI生成的用例虽然覆盖面广,但不代表每个case都有意义。有些case可能是重复的,有些case可能跟当前业务逻辑不符。让人工把一道关,既能保证用例质量,也能让测试同学在这个过程中学习AI的思路,慢慢提升自己的测试思维。
落地效果
搞了大概两个月,这套工具算是跑通了。说说效果:
测试用例数量翻了一倍多。 之前我们的接口自动化用例大概有1200条,现在增长到了2800多条。新增的用例里有不少是之前人工没覆盖到的边界场景。
用例编写时间缩短了60%左右。 以前测试同学写一个复杂接口的用例,可能要花半天时间。现在AI先生成一版,测试同学review和修改,通常一两个小时就搞定了。
线上bug率有所下降。 这个数据比较难精确统计,但从反馈来看,因为边界条件覆盖更全了,一些之前容易漏掉的case现在都能提前发现了。
当然,也有一些不足。比如AI对游戏业务中一些非常特殊的逻辑理解还不够深,像"抽卡的伪随机算法"、"匹配系统的ELO评分"这些,生成的用例就比较浅。这些还是得靠测试同学自己来补充。
跟运营同学的配合
说到测试,不得不提运营。我们游戏的运营活动特别多,每次新活动上线都会带来一批新接口。以前运营同学提需求的时候,接口文档经常写得很粗糙,导致测试同学拿到文档后一脸懵。
后来我们把AI用例生成器跟运营的需求文档也做了打通。运营同学在写需求文档的时候,系统会自动生成一份"测试关注点提示",列出这个活动可能涉及的测试场景。运营同学看到之后,就会主动把需求文档补充得更详细。
这个变化挺有意思的。本来是给测试用的工具,结果倒逼运营把需求质量也提上去了。算是意外之喜吧。
一些踩坑经验
最后分享几个我们踩过的坑,给想做类似事情的同学参考:
1. Prompt工程是个细活。 不要指望写一个万能prompt就能搞定所有场景。不同类型的接口、不同的业务模块,prompt的侧重点是不一样的。我们后来针对不同模块维护了多套prompt模板,效果才好起来。
2. 成本控制要注意。 GPT-4的API调用费用不便宜。我们一开始没做限制,测试同学生成用例的时候疯狂调用,一个月下来费用有点吓人。后来加了缓存机制——相同接口的用例生成结果会缓存起来,只有接口变更了才重新生成。
3. 别迷信AI。 AI生成的用例是起点,不是终点。一定要有人工review的环节,否则出了问题更麻烦。我们有一次就遇到过,AI生成的一个用例里,assert的条件写反了,导致一个bug没被测出来。
4. 文档质量是基础。 如果接口文档本身就写得乱七八糟,AI生成的用例质量也不会好。与其花大量时间调prompt,不如先把文档治理好。
写在最后
回头看看这半年的折腾,感触还是挺多的。AI这个玩意儿,说颠覆还早,但在一些具体的场景下确实能帮上忙。关键是要找到合适的切入点,不要为了用AI而用AI。
我们这套测试工具,说白了就是把AI当成一个"测试用例生成助手",干的是脏活累活。真正有价值的判断和决策,还是得靠人。
早上九点了,晨会的时间快到了。今天的分享就到这里,后面有机会再聊聊我们在K8s上做游戏服务部署的一些实践。
各位同行,共勉。


评论 0