单元测试在游戏编程中是否可行?

时间:2010-03-10 17:01:05

标签: unit-testing

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

考虑像playerJump(height)这样的简单操作。我希望有一个测试套件可以检查各种各样的情况,以确保跳跃始终按预期工作。但是,此功能可能不返回任何值,并且具有player.velocity.y = -heightcheckCollisions(player)的副作用。我想不出一个明确的单元测试来构建这个。

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


更新

来自Within的游戏有一系列关于在游戏中使用测试驱动开发的深度文章。我强烈推荐给任何对此主题感兴趣的人。这是第一篇文章:

http://gamesfromwithin.com/stepping-through-the-looking-glass-test-driven-game-development-part-1

7 个答案:

答案 0 :(得分:32)

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

那只是糟糕的设计。代码不会破坏任何东西。设计师必须在代码上强加一个结构,以便证明它实际上有效。

但是,此功能可能不会返回值...

因此?

...并且有player.velocity.y = -heightcheckCollisions(player)的副作用。

然后测试。

我想不出一个明确的单元测试来构建它。

为什么不呢?您刚刚给出了函数结果的优秀规范。

你可能需要一些模拟对象来用一个更容易测试的简化MockPlayer替换成熟的Player。

但是你的行为规范是完美的。只测试你描述的事情。

答案 1 :(得分:17)

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

当然,高级行为的区域很难进行单元测试,但这并不是单元测试的用途 - 它们主要用于检查单个方法或代码库的一小部分是否执行了它们应该执行的操作

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

您的PlayerJump示例就是这样一种情况。您可以通过使用常量输入隔离它来对其进行单元化或回归测试(以编程方式将玩家角色放置在简单测试场景中的固定位置并触发跳跃事件,然后检查他的碰撞或最终静止位置是否一致。玩家可以跳到“at”的不同对象的库,你可以覆盖很多测试用例(例如跳跃成功超过规定的最大跳跃距离)。

除此之外,游戏确实需要进行大量的游戏测试(真正的用户只是玩游戏)。这会发现你没有用自动化测试覆盖的奇怪案例,但更重要的是它会回答一个自动测试永远无法回答的问题:它“感觉”对吗?好玩吗”?这些只是人类可以进行的测试。

答案 2 :(得分:16)

单元测试对于许多可能与游戏代码一起使用的低级库非常有用,但我非常怀疑它对更高级别的东西有多大用处。游戏通常是模拟并依赖于大量的共享状态,这些状态无法有效地被单独模拟和测试。游戏中的函数通常不会返回任何可以立即检查的值,而是设置一个应该在将来的某个时刻完成的运动过程。测试此类行为是值得的,但需要采用明显不同的方法来单独测试代码片段的单元测试理念。

答案 3 :(得分:7)

我在Crysis 2开发过程中对单元和自动化测试的经验可以在这里找到: http://yetanothergameprogrammingblog.blogspot.com/2010/06/aaa-automated-testing.html 希望它有所帮助。

要点:

自动化测试提高了可交付成果的稳定性,提高了内容创建者和工程师的工作效率 自动化测试是提高代码质量和减少加班时间的有效工具 游戏行业作为一个整体是非常反动的,自动化测试遇到了几个不合理的论点 不要把它称为测试,称之为别的东西,几乎所有其他东西(看看行为驱动开发) 要灵活,编写好的测试很难,并且需要游戏行业无法广泛使用的技能

答案 4 :(得分:0)

单元测试根本不关心你的单元是多么“有状态”。你有一个或多或少独立的代码片段,如果它的输入和输出向量很大,那么测试很困难。在执行之前和之后这些向量是否被规定为状态并不会改变测试的一点。 但是,如果你想告诉我们你不能想出一个正确的方法来定义测试用例,就像在大多数简单的单元测试教程/论文中那样,即测试主题类似于“f(x)= y”,那么是的,我同意,你将很难证明人类甘蔗产生的少数(x [100],y [99])载体产生足够的覆盖率(数值!)。尝试制定综合属性和不变量,并进行自动化测试。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

许多游戏程序员使用Entity-component-system architecture。他们这样做是因为它可以更容易地修改游戏对象的行为。但实际情况是,它还可以更轻松地对代码进行单元测试。