关于 unity-test-runner
unity-test-runner 是一项用于从命令行运行 Unity Test Framework 并分析结果的技能,面向 Unity 开发者。它可筛选 EditMode 或 PlayMode 测试、解析失败详情并生成报告。
主要功能
- 01检测 Unity Editor 安装
- 02运行 EditMode 和 PlayMode 测试
- 03按类别或名称筛选测试
- 04解析 NUnit XML 结果
- 05分析失败及文件位置
- 06生成测试报告
适用场景
- 01验证 Unity 项目变更
- 02运行指定测试类别
- 03排查失败和堆栈跟踪
- 04将 Unity 测试用于 CI/CD
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dev-gom/ claude-code-marketplace --skill unity-test-runner安装后在 Claude Code 中输入/unity-test-runner确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/test-patterns.jsonscripts/find-unity-editor.jsparse-test-results.js详细介绍
Unity Test Runner
概述
此技能可直接从命令行自动执行和分析 Unity Test Framework 测试。它涵盖完整的测试工作流:检测各平台(Windows/macOS/Linux)上的 Unity Editor 安装、配置测试参数、执行 EditMode 或 PlayMode 测试、解析 NUnit XML 结果,并生成包含可执行建议的详细失败报告。
何时使用此技能
以下场景适合使用此技能:
- 从命令行执行 Unity Test Framework 测试
- 运行 PlayMode 或 EditMode 测试以验证游戏逻辑
- 分析测试失败并生成失败报告
- 将 Unity 测试集成到 CI/CD 工作流中
- 通过详细的堆栈跟踪和文件位置调试测试失败
- 在提交前验证 Unity 项目更改
用户请求示例:
- “运行我项目中的所有 Unity 测试”
- “执行 PlayMode 测试并向我展示结果”
- “运行 Combat 类别中的测试”
- “检查我的 Unity 测试是否通过”
- “仅运行 EditMode 测试”
工作流
调用此技能时,请遵循以下工作流:
1. 检测 Unity Editor 安装
使用 find-unity-editor.js 脚本自动查找 Unity Editor:
node scripts/find-unity-editor.js --json
脚本行为:
- 扫描各平台特定的默认安装路径
- 检测所有已安装的 Unity 版本
- 默认返回最新版本
- 可使用
--version <version>标志指定版本
输出:
{
"found": true,
"editorPath": "C:\\Program Files\\Unity\\Hub\\Editor\\2021.3.15f1\\Editor\\Unity.exe",
"version": "2021.3.15f1",
"platform": "win32",
"allVersions": ["2021.3.15f1", "2020.3.30f1"]
}
如果找到多个版本:
- 向用户列出所有可用版本
- 询问用户要使用哪个版本
- 或默认使用最新版本
如果未找到 Unity Editor:
- 报告错误并列出已搜索的路径
- 请用户手动提供 Unity Editor 路径
- 保存该路径以供后续使用
2. 验证 Unity 项目路径
使用跨平台检查,确认当前目录包含有效的 Unity 项目:
// Use Read tool to check for Unity project indicators
Read({ file_path: "ProjectSettings/ProjectVersion.txt" })
// Use Glob to verify Assets directory exists
Glob({ pattern: "Assets/*", path: "." })
验证步骤:
- 验证
Assets/目录是否存在 - 验证
ProjectSettings/ProjectVersion.txt是否存在 - 读取
ProjectVersion.txt以获取 Unity 版本 - 如果 Editor 版本与项目版本不匹配,则发出警告
ProjectVersion.txt 示例:
m_EditorVersion: 2021.3.15f1
m_EditorVersionWithRevision: 2021.3.15f1 (e8e88743f9e5)
3. 配置测试设置
确定测试执行参数。如果未指定参数,请使用 AskUserQuestion 工具:
必需设置:
- 测试模式:EditMode、PlayMode 或 Both
- 测试平台:EditMode 测试使用 "EditMode",PlayMode 可指定平台(例如 "StandaloneWindows64"、"Android"、"iOS")
可选设置:
- 测试类别:以分号分隔的列表(例如 "Combat;AI;Physics")
- 测试筛选器:正则表达式模式或以分号分隔的测试名称
- 结果输出路径:默认为项目根目录下的
TestResults.xml
配置示例:
AskUserQuestion({
questions: [{
question: "Which test mode should be executed?",
header: "Test Mode",
multiSelect: false,
options: [
{ label: "EditMode Only", description: "Fast unit tests without Play Mode" },
{ label: "PlayMode Only", description: "Full Unity engine tests" },
{ label: "Both Modes", description: "Run all tests (slower)" }
]
}]
})
4. 通过命令行执行测试
构建并执行 Unity 命令行测试命令:
命令结构:
<UnityEditorPath> -runTests -batchmode -projectPath <ProjectPath> \
-testPlatform <EditMode|PlayMode> \
-testResults <OutputPath> \
[-testCategory <Categories>] \
[-testFilter <Filter>] \
-logFile -
命令示例:
EditMode 测试:
"C:\Program Files\Unity\Hub\Editor\2021.3.15f1\Editor\Unity.exe" \
-runTests -batchmode \
-projectPath "D:\Projects\MyGame" \
-testPlatform EditMode \
-testResults "TestResults-EditMode.xml" \
-logFile -
使用类别筛选器运行 PlayMode 测试:
"C:\Program Files\Unity\Hub\Editor\2021.3.15f1\Editor\Unity.exe" \
-runTests -batchmode \
-projectPath "D:\Projects\MyGame" \
-testPlatform PlayMode \
-testResults "TestResults-PlayMode.xml" \
-testCategory "Combat;AI" \
-logFile -
执行说明:
- 对于长时间运行的测试,使用
Bash工具并设置run_in_background: true - 适当设置超时时间(默认:5-10 分钟,请根据测试数量调整)
- 监控输出中的进度指示
- 同时捕获标准输出和标准错误
执行示例:
Bash({
command: `"${unityPath}" -runTests -batchmode -projectPath "${projectPath}" -testPlatform EditMode -testResults "TestResults.xml" -logFile -`,
description: "Execute Unity EditMode tests",
timeout: 300000, // 5 minutes
run_in_background: true
})
5. 解析测试结果
测试完成后,使用 parse-test-results.js 解析 NUnit XML 结果:
node scripts/parse-test-results.js TestResults.xml --json
脚本输出:
{
"summary": {
"total": 10,
"passed": 7,
"failed": 2,
"skipped": 1,
"duration": 12.345
},
"failures": [
{
"name": "TestPlayerTakeDamage",
"fullName": "Tests.Combat.PlayerTests.TestPlayerTakeDamage",
"message": "Expected: 90\n But was: 100",
"stackTrace": "at Tests.Combat.PlayerTests.TestPlayerTakeDamage () [0x00001] in Assets/Tests/Combat/PlayerTests.cs:42",
"file": "Assets/Tests/Combat/PlayerTests.cs",
"line": 42
}
],
"allTests": [...]
}
结果分析:
- 提取测试摘要统计信息
- 找出所有失败的测试
- 从堆栈跟踪中提取文件路径和行号
- 按类型对失败进行分类(断言、异常、超时)
6. 分析测试失败
对于每个失败的测试,请使用 references/test-patterns.json 分析失败原因:
分析步骤:
- 加载测试模式数据库:
Read({ file_path: "references/test-patterns.json" })
-
将失败消息与模式匹配:
- 断言失败:
Expected: <X> But was: <Y> - 空引用失败:
Expected: not null But was: <null> - 超时失败:
TimeoutException|Test exceeded time limit - 线程错误:
Can't be called from.*main thread - 对象生命周期问题:
has been destroyed|MissingReferenceException
- 断言失败:
-
确定失败类别:
- ValueMismatch:断言值不正确
- NullValue:出现意外的空引用
- Performance:超时或执行缓慢
- TestSetup:Setup/TearDown 失败
- ObjectLifetime:访问已销毁的对象
- Threading:在错误的线程上执行
-
生成修复建议:
- 从 test-patterns.json 加载常见解决方案
- 将解决方案与失败模式匹配
- 提供具体的代码示例
失败分析示例:
**Test**: Tests.Combat.PlayerTests.TestPlayerTakeDamage
**Location**: Assets/Tests/Combat/PlayerTests.cs:42
**Result**: FAILED
**Failure Message**:
Expected: 90
But was: 100
**Analysis**:
- Category: ValueMismatch (Assertion Failure)
- Pattern: Expected/actual value mismatch
- Root Cause: Player health not decreasing after TakeDamage() call
**Possible Causes**:
1. TakeDamage() method not implemented correctly
2. Player health not initialized properly
3. Damage value passed incorrectly
**Suggested Solutions**:
1. Verify TakeDamage() implementation:
```csharp
public void TakeDamage(int damage) {
health -= damage; // Ensure this line exists
}
-
检查测试设置:
[SetUp] public void SetUp() { player = new Player(); player.Health = 100; // Ensure proper initialization } -
验证测试断言:
player.TakeDamage(10); Assert.AreEqual(90, player.Health); // Expected: 90
### 7. Generate Test Report
Create a comprehensive test report for the user:
**Report structure:**
```markdown
# Unity Test Results
## Summary
- **Total Tests**: 10
- **✓ Passed**: 7 (70%)
- **✗ Failed**: 2 (20%)
- **⊘ Skipped**: 1 (10%)
- **Duration**: 12.35s
## Test Breakdown
- **EditMode Tests**: 5 passed, 1 failed
- **PlayMode Tests**: 2 passed, 1 failed
## Failed Tests
### 1. Tests.Combat.PlayerTests.TestPlayerTakeDamage
**Location**: Assets/Tests/Combat/PlayerTests.cs:42
**Failure**: Expected: 90, But was: 100
**Analysis**: Player health not decreasing after TakeDamage() call.
**Suggested Fix**: Verify TakeDamage() implementation decreases health correctly.
---
### 2. Tests.AI.EnemyTests.TestEnemyChasePlayer
**Location**: Assets/Tests/AI/EnemyTests.cs:67
**Failure**: TimeoutException - Test exceeded time limit (5s)
**Analysis**: Infinite loop or missing yield in coroutine test.
**Suggested Fix**: Add `[UnityTest]` attribute and use `yield return null` in test loop.
---
## Next Steps
1. Review failed test locations and fix implementation
2. Re-run tests after fixes by re-invoking the skill
3. Consider adding more assertions for edge cases
报告交付:
- 以格式化的 Markdown 呈现报告
- 突出显示严重失败
- 提供文件:行号引用,便于快速定位
- 如果用户提出请求,主动提供协助以修复具体失败
最佳实践
使用此技能时:
-
先运行 EditMode 测试——速度更快,也能发现基本的逻辑错误
- 将 PlayMode 测试留给 Unity 特定功能
- 使用 EditMode 测试纯 C# 逻辑和数据结构
-
使用测试类别——筛选测试以加快迭代
-testCategory "Combat"仅运行 Combat 测试- 在开发特定功能期间很有帮助
-
监控测试时长——设置合适的超时时间
- EditMode:通常为 1-3 分钟
- PlayMode:通常为 5-15 分钟
- 根据测试数量调整超时时间
-
检查 Unity 版本兼容性——确保 Editor 与项目版本一致
- 版本不匹配可能导致测试失败
- 不同版本的测试结果可能不一致
-
立即解析结果——不要等待人工审查
- 自动解析能更快发现问题
- 提供可用于操作的文件:行号信息
-
分析失败模式——查找常见原因
- 相似的失败通常表明存在系统性问题
- 修复根本原因,而非单个症状
-
保留测试结果——保留 XML 文件以便调试
- 结果包含完整的堆栈跟踪
- 可用于比较测试运行结果
-
处理长时间运行的测试——使用后台执行
- 使用
BashOutput工具监控进度 - 向用户提供状态更新
- 使用
资源
scripts/find-unity-editor.js
跨平台 Unity Editor 路径检测脚本。自动扫描 Windows、macOS 和 Linux 的默认安装目录,检测所有已安装的 Unity 版本,并返回最新版本或指定版本。
用法:
# Find latest Unity version
node scripts/find-unity-editor.js --json
# Find specific version
node scripts/find-unity-editor.js --version 2021.3.15f1 --json
输出:包含 Unity Editor 路径、版本、平台和所有可用版本的 JSON。
scripts/parse-test-results.js
用于解析 Unity Test Framework 输出的 NUnit XML 结果解析器。从 XML 结果中提取测试统计信息、失败详情、堆栈跟踪和文件位置。
用法:
# Parse test results with JSON output
node scripts/parse-test-results.js TestResults.xml --json
# Parse with formatted console output
node scripts/parse-test-results.js TestResults.xml
输出:包含测试摘要、失败详情(含文件路径和行号)以及完整测试列表的 JSON。
references/test-patterns.json
Unity 测试模式、NUnit 断言、常见失败模式和最佳实践的综合数据库。包括:
- NUnit 断言参考(相等性、集合、异常、Unity 专属)
- 带正则表达式匹配的常见失败模式
- 失败类别和根因分析
- 带代码示例的解决方案模板
- EditMode 与 PlayMode 使用指南
- Unity 专属测试模式(协程、场景、预制体、物理)
- 测试最佳实践
用法:分析测试失败时加载此文件,以便将失败消息与模式匹配并生成修复建议。