TDD(测试驱动开发):作为开发模式,我以前在游戏开发中几乎没用过。我以前用的基本就是敏捷开发、原型模式,这些适合需要快速迭代的情况。但随着技术发展,LLM+Agent 能力与日俱增,TDD 这样以往不太适合游戏开发的模式现在却成为了最佳选择。

为什么是 TDD

        如果是传统的游戏开发,倒也确实不必要 TDD。TDD 最大的好处,就是给工程开发提供确定性,每一次修改、重构都能有一个可靠指标保证没有错误(不然无法通过测试用例)。但对于游戏开发,一大悲剧就是,需求本身都不明确,TDD 的基础都难以保证,测试用例自己的生命周期都如风中残烛,他所提供的可靠性自然无人在意。相信大家在游戏开发中经常遇到如此情况:我开发了一个功能,过几天就不要或者大改。那既然如此,我为他写一个甚至多个测试用例的意义在哪里呢?

 这就是 TDD 的最大痛点:设计测试用例的时间成本在快速功能变更中难以承受。

        那为什么现在又需要把 TDD 捡回来,而不继续使用传统开发模式呢?

        因为在 LLM+Agent 的开发模式下,时间成本被大幅压缩,平时十多个人两三个月的工作,现在一个人开几个 Agent 只需要不到 1 天就能完成。经过我自己的一些实际体验,使用 AI Agent 的人月效率大约是普通程序员的 100 倍左右。也就是说,普通程序员要 3 个月的工作,让 AI 来做只需要 1 天。此时,决定开发进度的原因也彻底改变了:

        以前是人的开发速度不够快,现在是人的验收速度不够快。

        所以,在当前情况下,TDD 的优势体现出来了:TDD 能够提前约定验收项目,从而让 AI 能满功率开发,不被人类的工作进度卡住。

        除此之外,更重要的一点,就是 TDD 是一个收敛的开发模型:当满足所有测试用例后,开发自然也就停止了。但不论是迭代、敏捷、原型,显然都是发散的开发模型,需求越做越多,系统越来越复杂,直到最后完全无法维护。

        但说实话,上述问题 TDD 也无法很好解决,并不是用了 TDD ,开发地狱的问题就会消失了。要解决着这个问题,还是要靠人的能力提升:团队如果自己都不知道要做什么,那也不是开发模型能解决的问题。

        但是,在 AI 时代,如果采用传统的开发模式,是会放大这些弊端:AI Agent 在没有良好约束的情况,犹如脱缰的野马,一路狂奔;等开发人员回过味来,已经来不及了。

        新的技术带来新的工作方式,在 AI 时代,最快的开发方式就是能让 AI 最快、最有效迭代的开发方式。此时,测试驱动开发成了最佳选择。

如何在 Unity 中使用 TDD

        在 Unity 中使用 TDD 有一个最为关键的问题:如何让代码脱离 C# 独立运行。由于 Unity 大量代码依赖其底层,导致无法直接在 Unity 外运行代码,即便无编译错误。而对于大模型开发,这一点就非常恼火:因为不能运行自然就无法正常跑测试用例,除非我们在每一个智能体开发设备上都放一个 Unity 编辑器。

        想要脱离 Unity 编辑器跑 Unity 代码目前来看是不现实的,现阶段也没有匹配的解决方案。因此,这里我建议进行如下操作:

About Unity Test Framework | Test Framework | 1.4.6 https://docs.unity3d.com/Packages/com.unity.test-framework@1.4/manual/index.html

  1. 在 Unity 内使用 Unity 自己的测试框架 Unity Test Framework 来编写测试用例。注意:这里编写测试用例时,建议严格区分纯逻辑(可脱离 Unity 运行,且无 Unity 依赖)部分和依赖 Unity 的部分,以便于部分测试能够脱离 Unity 运行。

  2. 在外部构建测试工程,用来编译项目代码(需引用 Unity 的 dll 和第三方插件的 dll),以及有一个能连上 Unity 编辑器真跑测试的脚本。

  3. 分两个轨道:A(静态轨):只进行静态编译测试,不跑逻辑,用于大模型常规开发使用,大模型可以自行判断逻辑问题。B(动态轨):可以用启动、运行的测试用例,由持有 Unity 编辑器的智能体运行并给出基线报告。

        在目前无法在外部 .Net 环境直接跑 Unity 代码时,这就是一个权宜之计,能够让当前项目直接用 Unity 就能够跑起来。

        当然上述都可以自动化进行,可以让 AI 写个 Unity 的命令行脚本,让 AI 能自动启动 Unity 测试框架进行测试、出基线报告;

基于 TDD 进行游戏开发

        首先,需要在 Unity 里建立不同的程序集,例如代码的框架层、业务层,然后测试需要单独一个特殊的程序集,可以让 Unity 自动创建一个:

        Window→General→Test Runner 打开面板:

        可以让 Unity 自动创建一个程序集。

        创建之后还需要我们手动引用需要的业务代码程序集(否则无法使用我们自己的代码),创建好示例如右图所示。如果有报编译错误需要引用的程序集,也可以自行引用即可。

        之后就可以自行编写测试代码了,例如:

public class Crc32Tests
{
    [Test]
    public void Compute_EmptyData_ReturnsZero()
    {
        uint result = Crc32.Compute(new byte[0]);
        Assert.AreEqual(0u, result);
    }
}

        之后就可以点击 RunAll 运行全部测试用例。

        当然,测试用例都不可能全部人工写,人工只会做一些典型使用场景的测试用例,重要的部分,其余的边界、异常值则由 AI 代劳了。

        一般来讲,按照 TDD 的标准流程,应该是在业务开始前就写测试用例,然后再实现功能:

        总之,TDD 的意义在于,能确保当前新的的功能没有引起新的逻辑问题回归,同时我们将功能的完成情况做成了一个可量化的指标(测试用例通过情况)。在后续的开发,尤其是使用 AI 开发时,我们能随时查看基线情况,来给项目以安全保证。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐