您想找什么?
Hero background image
Unity 项目的测试和质量保证技巧
此页面为机器翻译。如需查看原文以确保准确性并作为权威参考,

本文将介绍不同的测试实践,帮助您使用 Unity 发布更稳定的项目。

测试或质量保证(QA)是贯穿整个游戏开发周期的关键流程。经验丰富的开发人员都知道,您编写的任何代码都需要经过测试。

无论您是独立开发人员还是大型团队的一员(成熟的工作室通常都有专门的质量保证工程师),您都可以采用一系列测试和质量保证方法。

如果你喜欢运动和/或观看体育比赛,那么你就会知道,在许多比赛中,防守才是赢得冠军的关键。将您的 QA 流程视为您的防御策略,在发布性能和稳定性最佳的游戏时不放过任何机会。

为什么测试和质量保证很重要?

测试对于发现问题至关重要,例如代码中的错误、美工中的视觉效果,或者游戏设计和玩法中的用户体验问题。你可以开发出技术上最令人印象深刻的游戏,但如果它十有八九会崩溃,那么你的用户很快就会放弃它。

何时应在游戏开发周期中实施测试?

避免在游戏开发过程的最后阶段才进行测试。与其把测试看作是一个序列中的一个阶段,不如把它看作是游戏开发其他阶段的一个持续过程。在整个生产过程中和发货前测试您的想法和原型。每次发布游戏更新时,都要重复这一过程。

有一系列不同的测试技术可以更好地适应项目的不同阶段。

谁负责测试和质量保证?

您是没有专门质量保证团队的小型工作室成员吗?让朋友们组成一个工作组来帮助进行测试,或者选择第三方质量保证提供商来提供帮助。即使是拥有内部质量保证团队的工作室,也会经常使用外部公司提供额外的测试服务,如本地化测试(LQA)。

玩家测试可视为质量保证的一个子集,有助于确保您的游戏与目标受众和市场产生共鸣。在开发阶段,这个过程可以从玩家那里获得宝贵的反馈,从而改进游戏。

参与玩家测试的人员因测试的具体目标而异。不过,一般来说,让代表游戏目标受众的不同玩家群体参与进来非常重要。通过让不同类型的玩家参与玩家测试,游戏开发者可以从不同角度收集反馈意见,确保游戏吸引广大玩家。

如何对游戏进行质量保证和测试?

在以下章节中,您可以了解到常见的测试技术。这些方法可以结合使用,以确保代码库尽可能顺畅地运行。

在目标平台的各种设备上测试游戏也很重要。这尤其适用于移动游戏;您需要在不同的操作系统、屏幕尺寸和最低规格的移动设备上进行测试。这样做有助于为您的最低设备要求设定基准,当您为应用程序添加更多功能时,应不断重新审视每个类别。

在不同平台上进行测试不仅是为了找出潜在的游戏破解问题,了解长期或间接影响也很重要,例如移动游戏的电池耗尽或热过热问题。

Unity 编辑器中的单元测试对话
单元测试

单元测试是一种对游戏的单个单元或组件进行隔离测试的技术,有助于确保在开发过程中尽早发现错误,并确保对代码的修改不会破坏现有功能。

单元测试是通过编写小型测试用例来完成的,这些测试用例会对代码的特定行为进行测试。测试可针对单个脚本、游戏对象或游戏的特定功能进行。

在游戏开发中,应同时使用手动和自动的单元测试方法。

手动单元测试

手动测试包括让玩家玩游戏来测试其特性和功能。运行手动测试非常重要,因为有些问题自动测试可能无法发现,例如用户界面错误或不平衡或执行不佳的游戏或设计。

在 Unity 中进行手动单元测试的一个例子是为函数添加测试条件,并使用 Debug.Log 来输出函数通过或失败的标准(测试场景的输出)。

自动单元测试

自动单元测试需要编写代码,以自动隔离测试单个单元或代码片段。在 Unity 中,您可以为脚本、组件和其他游戏代码单元编写测试,这些测试可以作为测试套件的一部分运行。

Unity Test Framework(UTF) 软件包为开发人员提供了一个框架,使他们能够在 Unity 编辑器的编辑和播放模式下编写自己的自动测试。UTF 会在任何引用NUnit 的程序集内查找测试。此类程序集被称为TestAssemblies。播放模式和编辑模式测试需要在不同的程序集中进行。

UTF 在编辑器中提供了一个 "测试运行器"(Test Runner)窗口,帮助你运行和管理测试用例。

由于 UTF 使用测试程序集定义,因此需要将项目分解为运行时程序集定义。如果在开发过程中尽早进行规划,就会更容易做到这一点;它还能鼓励你编写更多模块化代码

Unity 软件包 "性能测试扩展 "是一个可以与 UTF 一起使用的扩展。它提供了额外的应用程序接口,用于测量和提供来自测试用例的自定义指标。

阅读视频游戏开发的 Unity 测试框架教程,了解如何开始使用Unity 测试框架

覆盖历史图表
测试驱动开发

测试驱动开发(TDD)是一种技术,包括在编写实际代码实现某项功能之前为其编写测试。这个过程通常包括编写一个失败的测试,编写使测试通过所需的最少代码量,然后重构代码使其更具可维护性,然后继续设计下一个测试用例。

TTD 在游戏开发中相当罕见(在主流软件开发中更为常见)。这可能是由于它在原型设计和制作有趣、引人入胜的游戏玩法方面是一个反直觉的过程。

不过,它可以加快识别游戏中被破坏部分的过程,因为任何破坏游戏的更改都会立即产生失败的测试用例。

有关 Unity 中 TDD 的更多信息,请参阅博文 "使用 Unity Test Runner 测试测试驱动开发"。

代码覆盖率

如果您想实施 TDD 或单元测试,请考虑使用 UnityCode Coverage 软件包。当与 UTF 一起使用时,代码覆盖软件包可以向您显示项目中哪些代码行正在接受测试,从而帮助您识别项目中存在漏洞或未经测试的部分。

代码覆盖还能在游戏模式下测试游戏时生成报告。这将向您展示您定期运行测试的代码部分,即使这些部分不在单元测试范围内。不过,虽然代码覆盖率报告会显示测试覆盖了哪些代码行,但不会显示代码中逻辑流动的不同路径。

请参阅博文 "Code Coverage:查找测试中的漏洞" 了解更多信息。

集成测试

集成测试是一种将系统的不同组件放在一起进行测试以确保其正常工作的技术。这包括测试不同的游戏对象、脚本或系统如何在游戏中相互影响。由于集成测试的范围更广,它可以帮助捕捉单元测试中可能不会出现的错误,如数据流或组件间通信的问题。

例如,可以为以下整个序列编写集成测试,而不是使用单独的单元测试:玩家发射武器并将其实例化为子弹,子弹击中敌人并将其击毙,玩家击毙敌人后获得分数,当玩家达到一定分数时成就被解锁。

您可以使用 UTF 在 Unity 中构建集成测试。使用SetUp 和 TearDown 方法,您可以创建一个环境,同时测试多个系统。可以模拟玩家逻辑和输入,尤其是在使用命令模式实现这些逻辑和输入的情况下(如果使用的是新的输入系统,则很可能已经实现),以便测试玩家输入到游戏逻辑的整个流程。

回归测试

回归测试是一种验证软件或功能在修改或更新后能否正常运行的方法。回归测试的目的是确保对代码库的更改不会在软件中引入新的错误或回归。这种技术最适用于频繁更新的大型复杂应用程序,例如实时游戏,在这种情况下,可能会有许多不同的组件以意想不到的方式进行交互。

随着游戏世界和机制的扩展,对回归测试的需求也在增加,这可能会导致成本高昂。因此,尽可能实现自动化非常重要。回归测试应与新功能的开发同步进行,尤其是在针对多个平台的情况下。

虽然回归测试最适合大型游戏和实时游戏,但其他因素,如软件的复杂性、更改或更新的频率以及受影响功能的重要性(任务或安全关键型系统)也决定了是否需要进行回归测试。

功能测试

功能测试根据功能要求对系统或软件应用程序进行测试,以评估其功能。这包括测试系统的功能、用户界面、数据库交互以及影响其行为和功能的其他方面。功能测试的目的是验证系统或应用程序是否符合客户或最终用户提供的要求和规格。

大多数单元测试都关注代码的特定路径,测试它是否根据特定输入返回正确的输出。它无法测试游戏是否达到了设计的目的。

功能测试就是这样一种方法。每个功能或特征都要与原始设计进行比较,以确定输出是否符合预期。这包括测试游戏的控制、游戏机制和整体用户体验。

在开发游戏时,将功能测试牢记在心,并采用 "先这样,再那样 "的方法创建任务,会很有帮助。例如,当玩家按下空格键时,角色应该跳跃:这既是对开发人员如何实现功能的指导,也是测试人员进行测试的验收标准。有时,一项功能可能包括一些相关的验收标准,如何时可以使用、何时不能使用。但它们一般应侧重于单一功能。

当需求定义明确、范围清晰时,功能测试才最有效。因此,它有助于与自由职业者或工作室签订合同,以提供游戏或游戏世界资产的组成部分。

您可以运行自动和手动功能测试。既要进行 "黑箱 "测试(在不了解系统内部运作的情况下测试系统),也要进行 "白箱 "测试(在了解系统内部运作的情况下测试系统)。

游戏 GPU 图形
性能测试

性能测试包括对游戏进行测试,以确保游戏在不同的硬件和软件配置下都能流畅高效地运行。这与剖析和一般性能优化工作流程密切相关,这种做法有助于找出可能影响游戏性能的性能瓶颈或问题。

主要目的是评估系统或应用程序在不同工作负载条件下的性能。在游戏开发中,性能测试衡量的是游戏运行的性能、帧速率、响应速度和稳定性是否达到可接受的水平,以及是否能最有效地使用内存。

不同类型的性能测试包括

  • 负载测试:确定游戏在承受大工作量时的表现
  • 压力测试:评估游戏如何处理意外情况,例如玩家活动突然增加的情况
  • 耐力测试评估游戏的长期表现

统一剖析器

Unity 中的Profiler工具可帮助您在开发游戏时分析游戏的性能。它既可在编辑器中使用,在开发过程中提供概览,也可在通过电缆或本地网络连接到机器的任何设备上使用,对游戏在目标设备上的运行情况进行准确分析。

可以对 Profiler 进行扩展,以自定义要捕获的数据类型和在 Profiler 窗口中的显示方式。

在 Unite 2022 课程 "如何在 Unity Profiler 中自定义性能指标 "中了解有关自定义 Profiler 的更多信息

您还可以编写自己的工具来创建自动性能测试。关于如何处理这一问题的有趣讨论,请参阅纪念碑谷开发商 ustwo Games 在 Unite 2022 上发表的演讲:"制作阿尔芭:如何构建性能卓越的开放世界游戏"

对指标和事件进行 A/B 测试
A/B 测试

测试不仅限于查找错误和监控性能。有时,您可能想对某一游戏功能的两个版本进行比较,以确定哪个版本的玩家参与度更高、表现更好。这就是所谓的A/B 测试

A/B 测试适用于修改会影响游戏平衡但游戏机制不变的角色或武器的属性。其他例子可能包括为比较不同教程、游戏机制或用户界面的有效性而进行的测试。通过分析从两个小组收集到的数据,您可以确定哪个版本的游戏或功能更有效,并根据数据做出决定,将哪些更改纳入最终产品。

A/B 测试包括将玩家随机分配到两组中:一组玩原版游戏或功能(对照组),另一组玩修改版游戏或功能(实验组)。

关键是要收集一小部分玩家受不同变化影响的数据,以帮助您做出设计决策,决定采用哪种方法作为广泛更新发布。

A/B 测试有助于改善用户体验,提高玩家参与度和留存率。它对拥有庞大用户群的游戏尤其有用,因为在这些游戏中,即使是用户参与度或留存率的微小改进也会产生重大影响。

A/B 测试通常是作为后台服务提供的,玩家甚至不会意识到他们正在使用不同的变体。Unity Gaming Services (UGS) 有一些工具可以帮助您在游戏中进行 A/B 测试,您可以在这里了解更多信息。您还可以查看UGS 使用案例(我们后台服务的样本集),了解如何在游戏中设置 A/B 测试。

诊断测试工具

Cloud Diagnostics Advanced 是一款由 Backtrace 提供支持的崩溃报告和分析工具,可与 Unity 集成,为开发人员提供有关游戏中崩溃和异常的详细信息。崩溃发生时,Cloud Diagnostics Advanced 会捕获崩溃时游戏状态的快照,包括环境、调用堆栈、堆和寄存器的相关信息。然后,该快照将被发送到 Backtrace 服务器,在那里进行分析,以确定崩溃的根本原因。

云诊断高级版还提供详细的分析和报告工具,可帮助您识别游戏性能和稳定性的长期趋势和模式。重复数据删除算法可根据代码中常见崩溃的根本原因对其进行聚类,从而帮助确定首先修复哪些错误的优先次序,尽可能提高大多数玩家的稳定性。

为游戏开发人员提供更多质量保证资源

无论使用哪种测试技术,重要的是要为如何测试游戏制定计划,并确保测试是开发过程中不可或缺的一部分。通过综合使用这些技术,您可以确保您的 Unity 游戏达到最高质量,并为制作做好准备。

Unity 现免费为程序员提供一系列新的电子书籍。每本指南都由经验丰富的程序员撰写,针对开发团队非常重视的特定主题提供最佳实践。

创建 C# 风格指南:编写更简洁、可扩展的代码 指导团队制定风格指南,帮助他们统一方法,创建更具凝聚力的代码库。

利用游戏编程模式提升代码水平重点介绍在您的 Unity 项目中使用 SOLID 原则和常用编程模式创建可扩展游戏代码架构的最佳实践。

使用脚本对象在 Unity 中创建模块化游戏架构提供了在游戏制作中部署 ScriptableObjects 的最佳实践。

我们创建这个系列的目的是为我们最有经验的创作者提供可行的技巧和灵感。但它们不是规则书!构建 Unity 项目的方法有很多种;在部署之前,请与同事一起评估每种建议、技巧和模式的优缺点。

Unity 最佳实践中心查找更多高级指南和文章。

您喜欢本文吗?
是的!
还行。