This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
自动化测试使用明确且机器可读的证据来验证 Defold 代码和内容。请使用本手册设计可供本地脚本、CI(持续集成)运行器和编码智能体共同使用的测试。本手册涵盖模块测试、运行集合、浏览器测试、运行时自动化、视觉检查、无头构建,并提供实用的良好实践。
良好的自动化测试层级遵循测试金字塔框架,将测试分为三个主要层次:单元测试、集成测试和端到端(E2E)测试。在 Defold 中,可以将测试划分到启动时加载的特定集合中。通常最好从能够检测问题的最小、最快检查开始,再按需添加运行时或平台测试。
| 层级 | 合适的证据 |
|---|---|
| 静态验证 | 解析器、格式化工具、资源验证器或生成文件比较的结果 |
| 模块测试 | 对引擎依赖最少的可复用 Lua 逻辑所产生的断言结果 |
| 运行集合 | 消息、组件、输入、物理、生命周期和引擎行为 |
| 运行时自动化 | 实时场景状态、注入的输入、应用程序状态和运行时截图 |
| HTML5 浏览器测试 | 画布输入、浏览器集成、视口行为和 Web 输出 |
| 平台测试 | 实际目标平台上的行为和渲染结果 |
| 构建和打包 | Bob 退出状态、构建报告、存档和包产物 |
编译成功只证明项目能够构建,并不能证明游戏行为正确。截图无法证明复杂的过渡、动画、交互或游戏流程,但现代多模态解决方案可以用它检查某一帧的外观,以及着色器和视觉布局是否正确。不过,对于自动化测试,只要条件可以直接表达,就应优先使用确定性断言。
将可复用逻辑放在对引擎依赖最少的 Lua 模块中。这样,无需构建完整游戏世界即可测试纯数据转换、规则、状态机和计算。
将面向引擎的代码与它所调用的逻辑分离。脚本可以把消息和组件状态转换成对模块的调用,而测试则使用受控输入直接调用模块。
更多详情请参阅编写代码手册。
当行为依赖于游戏对象、组件、消息、输入、物理或其他引擎系统时,请使用专用的测试集合。
每项测试都应:
测试应优先使用彼此隔离的测试集合。项目可以通过 game.project 中的临时项目设置选择测试启动集合:
[bootstrap]
main_collection = /test/test.collectionc
不要在项目的常规配置中保留临时测试启动集合。在 CI 中,应优先使用传递给 Bob 的专用设置文件。CI 不应更改代码仓库的状态,只应在需要时进行临时更改。
对于复杂游戏,可以创建带有预定义情境和简单白盒场景的小型“开发房间”集合。它们可以让机制易于复现,并简化测试开发,而无需在无关的游戏状态和区域中导航。
项目可以实现一个小型运行器,或使用社区测试库。
例如,DefTest 是基于 Telescope 的单元测试库。它支持测试套件、建立和清理函数、断言、名称过滤、针对部分 Defold API 的模拟,以及可选的 LuaCov 覆盖率。测试可以从专用的启动集合运行,也可以在使用 Bob 创建的无头包中运行。
框架的控制台或日志摘要对开发者很有帮助,但无人值守的自动控制器仍需要明确的完成结果。如有必要,可在框架回调或摘要周围添加小型适配器,以便控制器轻松处理测试结果。
一种简单的结果描述格式,是在控制台的每个物理行上使用唯一前缀,后接一个 JSON 对象:
TEST {"run":"8f13","event":"suite_start","tests":2}
TEST {"run":"8f13","event":"case","name":"player_moves","status":"pass","duration_ms":3}
TEST {"run":"8f13","event":"case","name":"player_stops","status":"pass","duration_ms":2}
TEST {"run":"8f13","event":"suite_end","status":"pass","passed":2,"failed":0}
收集器应独立处理每一行,查找 TEST 前缀,解析其后的 JSON,并忽略无关的引擎输出。
请包含唯一的运行标识符,以防旧进程或并发进程的输出被误判为当前运行完成。每个套件都应输出一个含义明确的最终事件(如 Pass、Failure、Crash、Timeout 等)。
从编辑器运行游戏时,编辑器既会提供当前控制台历史记录,也会提供连续输出流。应在收到匹配的测试套件完成事件、进程终止、发生错误,或达到配置的超时和行数限制后关闭该流。
请在编辑器 HTTP API 手册中了解更多信息。
Defold 还可以通过启用 Write Log File(位于 game.project 中)来持久保存游戏日志。请参阅游戏和系统日志。文件日志适用于打包后的应用程序,以及编辑器控制台不可用时对目标设备的测试。
项目可以使用内置的 print() 和 pprint() 函数,或使用资产门户中的其他日志记录库。
运行时自动化 API 可以检查和控制实时调试引擎。当测试必须查找运行时对象、注入输入、等待可见状态或捕获渲染结果时,可以使用该 API。
更多详情请参阅引擎服务手册。
以下示例使用 Automation Bridge Python 辅助工具的结构。项目必须包含兼容版本的调试扩展,公开具有给定自动化 ID 的元素,并发布 screen 应用程序状态:
from automation_bridge import editor
project = editor.open_project(".")
game = project.build_and_run()
try:
play = game.element(automation_id="play_button")
game.click(play)
game.wait_for_state("screen", "gameplay", timeout=5.0)
screenshot = game.screenshot()
print(screenshot.path)
finally:
game.close_engine()
应用程序定义的状态和自动化 ID 使用 Automation Bridge 可选的仅调试 Lua API,项目必须启用并发布这些内容。固定的休眠时间容易受机器速度和帧时序影响;对明确定义的状态进行有界轮询会更加可靠。
Automation Bridge 是一个扩展,而不是核心引擎的一部分。请查阅其 Python API 参考,了解所安装版本的选择器、等待、状态、事件、截图和诊断功能。
编辑器可以通过当前的 build-html5 命令创建并提供 HTML5 构建,具体请参阅编辑器 HTTP API 手册。Bob 也可以在不使用编辑器的情况下创建 HTML5 包。
Playwright、Puppeteer、Selenium、WebdriverIO 或 Cypress 等外部浏览器自动化工具可以:
指向画布的输入会通过项目的常规输入绑定和 on_input() 回调进行处理。测试时应同时检查游戏响应和浏览器专用的集成点。
最可靠的方法是在自定义 index.html 中公开一个明确的 JavaScript 测试桥接。在 Defold 端,HTML5 构建可以使用 html5.run() 执行 JavaScript,从而与此类浏览器端桥接进行通信。对于从 JavaScript 传回 Defold 的命令,请使用专用的 JavaScript 到引擎桥接。
浏览器测试应有明确的范围限制。在最终报告中区分页面加载失败、画布缺失、JavaScript 错误、测试超时和游戏断言失败。
可以在打开的编辑器默认场景视图中为资源文件创建“截图”,也可以在运行时游戏中创建截图。
| 方法 | 用途 |
|---|---|
| 编辑器预览 | 已加载资源的布局,例如关卡或 GUI、图集构成、瓦片地图检查、静态场景构成、编辑器渲染和着色器正确性,或制作文档缩略图 |
| 运行时截图 | 受控情境中运行构建的渲染状态 |
例如,可以使用图像比较进行回归测试。检查失败时,请保存差异图像和比较指标。
多模态模型可以在视觉检查中评估难以用其他方式表达的语义条件,例如文本被截断、控件重叠、选择状态不明确或内容超出安全区域。建议将这种评估视为具有明确标准的附加信号,而不是确定性逻辑检查或图像比较的替代品。
使用 Bob 构建器 CLI 工具执行独立于编辑器的 CI。
您可以使用它解析依赖项、构建游戏、存档或独立包,并生成 JSON 报告:
mkdir -p build/reports
java -jar bob.jar \
--root . \
--archive \
--build-report-json build/reports/build-report.json \
resolve build
使用专用设置构建无头测试包:
java -jar bob.jar \
--root . \
--settings test/test.settings \
--platform x86_64-linux \
--variant headless \
--archive \
--bundle-output build/test-bundle \
resolve build bundle
使用适合平台的进程控制器运行生成的可执行文件。捕获其退出状态和日志,实施超时,并要求输出结构化的测试套件完成事件。
Bob 手册介绍平台、设置文件、包、缓存、原生扩展和构建报告。
良好的测试结果应保留足够的证据来复现和诊断故障:
开发者、本地脚本、CI 服务或 AI 编码智能体应能够使用同一种格式。这样,即使将诊断或修复工作委派出去,验证本身仍然具有确定性。