Unit testing 单元测试在游戏编程中可行吗?

Unit testing 单元测试在游戏编程中可行吗?,unit-testing,Unit Testing,我喜欢单元测试的想法,但我在将其应用于游戏编程时遇到了困难。游戏是高度有状态的,而且代码通常不会将自己分解成不同的单元。根据我的经验,大多数函数都会改变状态,而不是返回值 考虑一个简单的动作,比如playerJump(height)。我希望有一个测试套件来检查各种各样的情况,以确保跳转总是按照预期工作。但是,此函数可能不会返回任何值,并且会产生副作用,player.velocity.y=-height和检查碰撞(player)。我想不出一个清晰的单元测试来构建它 单元测试在像游戏这样的高状态应用

我喜欢单元测试的想法,但我在将其应用于游戏编程时遇到了困难。游戏是高度有状态的,而且代码通常不会将自己分解成不同的单元。根据我的经验,大多数函数都会改变状态,而不是返回值

考虑一个简单的动作,比如
playerJump(height)
。我希望有一个测试套件来检查各种各样的情况,以确保跳转总是按照预期工作。但是,此函数可能不会返回任何值,并且会产生副作用,
player.velocity.y=-height
检查碰撞(player)
。我想不出一个清晰的单元测试来构建它

单元测试在像游戏这样的高状态应用程序中不可行吗?单元测试的优势是否如此之大,以至于在功能上编程游戏是值得的


更新:

《内部游戏》有一系列关于在游戏中使用测试驱动开发的深入文章。我强烈推荐给对这个主题感兴趣的人。以下是第一篇文章:

代码通常不会将自身分解为不同的单元

那只是拙劣的设计。代码本身不会分解成任何东西。作为设计师,你必须在代码上加上一个结构,这样你才能证明它确实有效

但是,此函数可能不会返回任何值

那么

…并产生副作用,
player.velocity.y=-height
检查碰撞(player)

然后测试一下

我想不出一个清晰的单元测试来构建它

为什么不呢?您刚刚对函数的结果给出了一个很好的说明

您可能需要一些mock对象来用更易于测试的简化MockPlayer替换完整的播放器


但你的行为规范是完美的。只需对您描述的内容进行测试。

单元测试对于您可能在游戏代码中使用的许多低级库非常有用,但我严重怀疑它对于高级库是否有多大用处。游戏通常是模拟的,依赖于大量的共享状态,而这些共享状态并不能被孤立地模拟和测试。通常情况下,游戏中的函数不会返回任何类型的值,您可以立即检查这些值,而是设置一个进程,该进程应该在将来某个时候完成。测试这种行为是值得的,但需要一种与单元测试理念截然不同的方法,即单独测试代码片段。

单元测试根本不关心单元的“状态”。您有一段或多或少自包含的代码,如果它的输入和输出向量很大,那么测试就很困难。无论这些向量是否作为执行前后的状态进行设置,测试都不会有任何变化。
然而,如果你想告诉我们,你不能像大多数头脑简单的单元测试教程/论文那样,想出一个合适的方法来定义测试用例,即测试主题类似于“f(x)=y”,那么,是的,我同意,你将很难证明人类能够产生的少数(x[100],y[99])向量能够产生足够的覆盖率(数字!)。尝试制定综合属性和不变量,并进行自动测试。

看看自动单元测试生成。它将为所有可能的输入变量生成单元测试,这将帮助您测试许多可能的组合。

编程就是编程。单元测试对任何类型的应用都很有用因为它们可以帮助您立即高效地检测和纠正错误(通常更重要的是,在重构代码时无意中引入了回归)

当然,有一些高级行为领域很难进行单元测试,但这并不是单元测试的真正目的——它们主要用于检查单个方法或代码库的一小部分是否完成了它们应该做的事情

对于更高级别的行为,您需要应用其他测试方法(回归测试,例如:向游戏中输入固定的输入序列,然后检查每次获得的结果是否相同,或者在整个级别的固定位置生成摄影机视图,并检查它们是否始终生成相同的结果)(或至少是合理相似的)图像)

您的PlayerJump示例就是这样一种情况。您可以通过使用常量输入隔离它来对其进行单元或回归测试(通过编程将玩家角色放置在一个简单测试场景中的固定位置,启动跳跃事件,然后检查其碰撞或最终休息位置是否一致。通过建立玩家可以“跳跃”的不同对象库,可以覆盖大量测试案例(例如,跳跃成功越过规定的最大跳跃距离)


不过,除此之外,游戏确实需要大量的游戏性测试(真正的用户只是玩游戏)。这会发现一些奇怪的情况,而自动化测试并没有涵盖这些情况,但更重要的是,它将回答一个自动化测试永远无法回答的问题:它“感觉”对吗?它“有趣”吗?这些测试只有人类才能进行。

我在Crysis 2开发过程中的单元测试和自动化测试经验如下: 希望能有帮助

总结:

自动化测试提高了交付物的稳定性,提高了内容创建者和工程师的生产效率 自动化测试是提高代码质量和减少加班的有效工具 游戏行业作为一个整体是非常反动的,一般来说,自动化测试会遇到一些不合理的反对意见 不要称之为测试,称之为其他,几乎任何其他(看看行为驱动的开发) 要灵活,编写好的测试是很难的,而且需要的技能在游戏行业并不普遍

许多游戏p