转载

LOL开发者谈网游自动化测试:每天10万次

  对于一款在线游戏来说,游戏发布往往只是开始,随后就需要不断地给游戏增加新的内容或者游戏模式。但是每一次的更新都需要大量的游戏测试,玩家数越多的游戏所需要的测试量也越大。作为同时在线突破过 750 万、MAU 超过了 6700 万的《英雄联盟》来说,Riot 公司每次新版本发布需要的测试量是难以想象的。

LOL开发者谈网游自动化测试:每天10万次

  最近,在该公司的官方技术博客中,Build 验证系统开发团队负责人 Jim ‘Anodoin’ Merrill 讲述了 Riot Games 为《英雄联盟》采取的自动化测试方案,据他透露,这款 MOBA 游戏每天的自动化测试数超过 10 万个,以下请看 Gamelook 编译的内容:

  大家好,我是 Jim ‘Anodoin’ Merrill,为《英雄联盟》做自动测试方面的工作,特别专注于游戏内体验。我目前担任 Build 验证系统研发(BVS-Dev)团队的队长。很大程度上,我们团队主要是为自动化测试打造工具并帮助团队写出更好的测试程序。

  过去的几年里,我们一直都在打造测试系统和基础设施,主要是为了提高开发者们的效率并降低游戏中的 bug 数量。我们现在每天要运行 10 万个测试案例,对于这个测试量,自动化测试可以帮助我们把内容更快地推送到玩家们面前,而且可以减少 bug。我希望分享一些我们所尝试过的一些做法,也希望能够开启游戏领域有关自动化测试方面的讨论。

  为什么我们要在意自动化测试呢?

  《英雄联盟》的变化非常之快,平均来说,在每天的源代码管理检查中都可以看到超过 100 个与代码和内容相关的改变,而要覆盖所有的这些改变就是一个挑战。随着每两周推一次更新的速度,我们快速检查故障就变得极其重要。在发布过程中的 bug 发现太晚就会导致更新的发布延迟,导致重新部署更新内容,或者必须暂时禁用某些英雄,这些对于玩家们来说都是糟糕的体验。自动化测试可以让品质分析师们更多地专注于创意测试和上游故障的预防,这样他们可以创造更多的价值。

  自动化测试还可以更快地显示测试结果,对于人类来说,对于提交的每一行新代码或者内容都进行完整的测试是不现实的,即便是能够做到,那也需要大量的测试者参与并且快速地返回足够多的测试结果。

  我们的测试系统运行基于持续集成(CI),并且在大约一小时后反馈报告。这就意味着开发者们收到结果的时间是相对合理可控的,这可以减少上下文切(context switching)换次数和时间。实际上,自动化测试中发现的 bug 解决速度比普通的 bug 快 8 倍。更好的是,如果我们需要给测试增加吞吐量的话,只要简单的给测试集群系统增加一些执行程序就可以了。

  Build 验证系统

  这个带有想象力色彩的 Build 验证系统(BVS)是我们为游戏客户端和服务器打造的测试框架,它负责获取测试资料,把它们应用到测试机器上,开始并管理测试系统、执行测试并且报告各自的测试结果。测试和线束都是用 Python 写的,而且我们写了大多数的 BVS 代码,这样可以帮助测试程序写作者们不用受到收集必须的资源所带来的麻烦。因此,一些测试类当中的参数可以确定运行什么地图、需要加入多少客户端以及什么英雄需要在游戏中(被测试)。

  测试使用客户端和服务器上的远程程序调用端点来解决指令并监控游戏状态。大多数情况下,测试包含一套相对线性化的指令和查询,现有的测试覆盖了从英雄技能到视觉规则以及杀死一个怪应该获得的奖励等所有方面。我们一些早期测试并没有那么线性化,但这样的做法让非技术开发者们对于这个系统的使用更加困难。由于确定测试环境的所有工作都是独立完成的,所以测试本身不管是在本地工作室还是在测试集群中进行都是一样的。所以这让本地运行测试更加容易,而且给游戏做出改变也更容易。

  比如我们对深渊巨口·克格莫新W技能的伤害处理测试看起来是这样的:

LOL开发者谈网游自动化测试:每天10万次

代码截图(详细代码请移步至 Riot 官博)

  克格莫测试的第一个部分包括了生化弹幕技能的伤害测试,看起来是这样的:

LOL开发者谈网游自动化测试:每天10万次

  当测试完成运行之后,它就会给独立的报错服务提供测试结果,该服务大概可以存储 6 个月的运行数据。基于特定测试数据的来源不同,该服务还会采取不同的措施。本地运行测试会打开执行器上的网页,它上面详细技术了失败和成功的案例。然而在测试集群中进行的测试会给所有一经发现过的问题创造新的 bug 标签,根据结果给对象增加标记,如果有失败案例的话,就会给测试执行者发送邮件。测试数据还通过报错服务进行汇总和追踪,可以让我们看到测试失败是什么时候发生的、发生的频率以及距离通过的版本出现有多少时间等等。

LOL开发者谈网游自动化测试:每天10万次

在 wood 5 中我们没有使用任何监控,所以看不到这次重大故障的问题所在

  为了避免古怪或者不可靠的测试,每一个测试都必须通过标准处理过程才能被信任。在一个测试进行了代码审核并且提交之后,它就进入了一系列被称为 BVSStaging 的测试。这时候,测试必须展示出至少一周的稳定性才能被提出来使用。如果 staging 阶段的测试失败,那么结果就只会让测试开发者们知道,这样会避免整个团队的困惑。

  一旦测试展示了可靠性之后,它就会被提到两套程序中的一个。首先是 BVSBlocker,它包含的测试能够确定一个 build 是否值得进一步测试,不能通过 Blocker 测试的 build 是不会应用到测试环境中的,因为要么是游戏不能运行,要么就是有很多严重的 bug 影响游戏性能。另一套是 BVSCore,也是我们功能测试的核心,包括对于每个英雄技能的测试。

  深度探索框架

  BVS 通过三个层面实现:执行器、驱动器以及脚本。执行器接入一个功能测试的通用 API,驱动器则加入特定步骤的配置并且执行测试。最后,脚本为测试案例加入特定的逻辑。目前情况下,我们只有一个在使用中的驱动器(也就是 LOLGame),但执行器和驱动器分离的做法,意味着我们未来的项目可以通过加入它们自己的驱动器使用 BVS,并且共享编写 LOLGame 驱动器的工具。

LOL开发者谈网游自动化测试:每天10万次

流程图

  它们需要的单个组件注册器和可选参数都是其各自声明(declaration)的一部分,当参数提供到指令栏的时候,它们被存储为组建消耗作为初始化部分的关联数组(dictionary)。初期版本的 BVS 针对 Python 使用标准的 argparse 库,但我们选择不使用 argparse 库的原因有两个方面:首先,潜在的参数输入量会变的更大,因此很难在系统中进行追踪;第二,驱动器需要拥有驱动器特有的参数,这也就意味着在启动时生命解析器是不可行的。

LOL开发者谈网游自动化测试:每天10万次

一个驱动器类的示例参数

  这里有三个层面的相关粒度:测试集、测试和测试案例。

  测试集是共同运行的一组测试的集合,比如前面提到的 BVS Blocker 测试集是一系列运行在 CI 上的冒烟测试(smoke test),测试集目前是通过 JSON 文件向 BVS 描述的,这些文件可以早期创建,也可以在测试过程中生成。

  测试指的是加入了一系列使用相同游戏参数的类似测试栏里的(单独的)类,比如,LoadChampsAndSkins 测试通过运行加载每个英雄和皮肤资源的测试案例来实现,并且要确定加载是合理的。

  测试案例指的是在一次测试中将要起到一定功能的单位,比如,LoadChampsAndSkin 测试中的 loadChampionAndSkin 函数就是一个单独的测试案例,这个案例会被执行数百次,因为要匹配每个英雄和皮肤之间的关系。克格莫的整套测试案例是通过高级测试被执行的,这些测试可以允许更为复杂的测试案例拥有比函数更多的结构。

  BVS 里的并行化基本上是在测试设定层面就做好了,当然也可以发生在测试期间,因为 BVS 把测试集当作 JSON 存储和读取,我们在这个 JSON 里创造了子列表,既可以通过单个执行器连续执行,也可以在测试群里并行执行。在 BVS 的初期,我们可以手动平衡,因为对于比较小的测试列表来说,手动比自动化效率更高。随着使用中的主要测试集不断增多,我们开始转向了可以产生同样 JSON 文件的自动化加载平衡器,但我们现在用的是在过去 10 次运行中的每个测试组件所用的平均时间。

  大多数的 BVS 用户只对于测试本身感兴趣,因为我们也开始用自己的方式寻找出路,确保他们不用考虑驱动器处理的所有细节。同样的是,我们使用了相对比较大的标准库,它包含了 PRC 端点。我们这么做的最主要原因只是为了确保测试没办法留后路,但最重要的原因是,我们把它当作一系列的行为标准,既能预防马虎的测试程序编写,还能确保不同测时间的连贯性。

  特别是我们在 BVS 的标准测试库里不用任何形式的 sleep 函数,只有测试程序写作者才会更多地用到 sleep 函数,这就导致了由于硬件不同而产生的测试差异化,在标准数据库模式下的所有 wait 函数都是条件 wait 函数,这会让游戏有一个稳定的挤走,只有条件被满足的时候才执行。

LOL开发者谈网游自动化测试:每天10万次

wait 条件函数案例

  自初期开始,我们为 BVS 采用了一个主要方法就是,把和所有市相关的逻辑都分离开来。过去 BVS 还承担了确认应该使用哪些资源的作用,为了保持职责分工的清晰,我们专门有个独立的服务,它负责所有和运行测试没有直接关联的工作,这个服是使用了 Django REST 框架的 Django 应用,它可以提供一个 BVS 和当前 BVS 其他服务可以用的 API。

LOL开发者谈网游自动化测试:每天10万次

运行和运行后流程(点击放大)

  整体性能

  整体来说,《英雄联盟》每次推出新版本之后,BVS 在 18 分钟里运行大约 5500 个测试案例,总的来说就是每天运行 10 万次测试。从故障提交到 BVS 得出首个测试报告的时间大约在一两个小时之间。50% 的重大或者拦路虎级别的 bug 都是被 BVS 发现的,其余则是在内部 QA 或者在 PBE 上发现的。没有被 BVS 发现的问题通常都是直接跳过的,因为测试覆盖面不够广,而不是测试做的不好。

  虽然我们发现的大多数 bug 都是游戏崩溃或者功能缺失方面的,但通常我们也会最先发现一些真正难以发现的 bug。我个人比较喜欢的一个 bug 是,游戏中所有的塔都向地图的右上角倾斜,导致产生了史诗级的塔防效果图。我们发现的还有非自动化测试不一定能够发现的问题,比如如果一个英雄在射程范围的边缘对敌人施放技能可能会导致 miss。

  总体来说,自动化测试并不一定要取代人工测试,但它毫无疑问地加快了反馈周期,让我们的人工测试者们有更多的自由用在具有建设性的测试上。随着越来越多的内容被加入到《英雄联盟》中,我们还会覆盖更多的测试范围,这毫无疑问会提高我们的销量并改善游戏版本的表现。

正文到此结束
Loading...