chore(unity): 固定Unity CLI Loop本地包并移除UnitySkills依赖
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
|
||||
namespace io.github.hatayama.uLoopMCP
|
||||
{
|
||||
/// <summary>
|
||||
/// Response schema for RunTests command
|
||||
/// Provides type-safe response structure
|
||||
/// </summary>
|
||||
public class RunTestsResponse : BaseToolResponse
|
||||
{
|
||||
public const string TestFrameworkUnavailableMessage =
|
||||
"run-tests requires the Unity Test Framework package (com.unity.test-framework). Install it via Package Manager to use test execution.";
|
||||
|
||||
/// <summary>
|
||||
/// Whether test execution was successful
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Test execution message
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Test execution completion timestamp
|
||||
/// </summary>
|
||||
public string CompletedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total number of tests executed
|
||||
/// </summary>
|
||||
public int TestCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of passed tests
|
||||
/// </summary>
|
||||
public int PassedCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of failed tests
|
||||
/// </summary>
|
||||
public int FailedCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of skipped tests
|
||||
/// </summary>
|
||||
public int SkippedCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path to XML result file (if saved)
|
||||
/// </summary>
|
||||
public string XmlPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new RunTestsResponse
|
||||
/// </summary>
|
||||
public RunTestsResponse(bool success, string message, string completedAt, int testCount,
|
||||
int passedCount, int failedCount, int skippedCount, string xmlPath = null)
|
||||
{
|
||||
Success = success;
|
||||
Message = message;
|
||||
CompletedAt = completedAt;
|
||||
TestCount = testCount;
|
||||
PassedCount = passedCount;
|
||||
FailedCount = failedCount;
|
||||
SkippedCount = skippedCount;
|
||||
XmlPath = xmlPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameterless constructor for JSON deserialization
|
||||
/// </summary>
|
||||
public RunTestsResponse()
|
||||
{
|
||||
Message = string.Empty;
|
||||
CompletedAt = string.Empty;
|
||||
XmlPath = string.Empty;
|
||||
}
|
||||
|
||||
public static RunTestsResponse CreateTestFrameworkUnavailable()
|
||||
{
|
||||
return new RunTestsResponse(
|
||||
success: false,
|
||||
message: TestFrameworkUnavailableMessage,
|
||||
completedAt: DateTime.UtcNow.ToString("o"),
|
||||
testCount: 0,
|
||||
passedCount: 0,
|
||||
failedCount: 0,
|
||||
skippedCount: 0,
|
||||
xmlPath: null
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e07c934664e244f7bb0c9928d6ac9c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace io.github.hatayama.uLoopMCP
|
||||
{
|
||||
// Mirrors Unity Test Runner mode names without making the command schema depend on Test Framework types.
|
||||
public enum RunTestMode
|
||||
{
|
||||
EditMode = 1,
|
||||
PlayMode = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supported test filter types
|
||||
/// </summary>
|
||||
public enum TestFilterType
|
||||
{
|
||||
all = 0,
|
||||
exact = 1,
|
||||
regex = 2,
|
||||
assembly = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schema for RunTests command parameters
|
||||
/// Provides type-safe parameter access with default values
|
||||
/// </summary>
|
||||
public class RunTestsSchema : BaseToolSchema
|
||||
{
|
||||
/// <summary>
|
||||
/// Test mode - EditMode(1), PlayMode(2)
|
||||
/// </summary>
|
||||
[Description("Test mode - EditMode(1), PlayMode(2)")]
|
||||
public RunTestMode TestMode { get; set; } = RunTestMode.EditMode;
|
||||
|
||||
/// <summary>
|
||||
/// Type of test filter - all(0), exact(1), regex(2), assembly(3)
|
||||
/// </summary>
|
||||
[Description("Type of test filter - all(0), exact(1), regex(2), assembly(3)")]
|
||||
public TestFilterType FilterType { get; set; } = TestFilterType.all;
|
||||
|
||||
/// <summary>
|
||||
/// Filter value (specify when filterType is not all)
|
||||
/// • exact: Individual test method name (e.g.: io.github.hatayama.uLoopMCP.ConsoleLogRetrieverTests.GetAllLogs_WithMaskAllOff_StillReturnsAllLogs)
|
||||
/// • regex: Class name or namespace (e.g.: io.github.hatayama.uLoopMCP.ConsoleLogRetrieverTests, io.github.hatayama.uLoopMCP)
|
||||
/// • assembly: Assembly name (e.g.: uLoopMCP.Tests.Editor)
|
||||
/// </summary>
|
||||
[Description("Filter value (specify when filterType is not all)\n• exact: Individual test method name (e.g.: io.github.hatayama.uLoopMCP.ConsoleLogRetrieverTests.GetAllLogs_WithMaskAllOff_StillReturnsAllLogs)\n• regex: Class name or namespace (e.g.: io.github.hatayama.uLoopMCP.ConsoleLogRetrieverTests, io.github.hatayama.uLoopMCP)\n• assembly: Assembly name (e.g.: uLoopMCP.Tests.Editor)")]
|
||||
public string FilterValue { get; set; } = "";
|
||||
|
||||
[Description("Save unsaved loaded Scene changes and current Prefab Stage changes before running tests")]
|
||||
public bool SaveBeforeRun { get; set; } = false;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fcfc452995c36409e993e09326c2693d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace io.github.hatayama.uLoopMCP
|
||||
{
|
||||
/// <summary>
|
||||
/// Test execution tool handler - Type-safe implementation using Schema and Response
|
||||
/// Executes tests using Unity Test Runner and returns the results
|
||||
///
|
||||
///
|
||||
/// This Tool class delegates to RunTestsUseCase for business logic execution,
|
||||
/// following the UseCase + Tool pattern for separation of concerns.
|
||||
///
|
||||
/// Related classes:
|
||||
/// - RunTestsUseCase: Business logic and orchestration
|
||||
/// - RunTestsSchema: Type-safe parameter schema
|
||||
/// - RunTestsResponse: Type-safe response structure
|
||||
/// </summary>
|
||||
[McpTool(
|
||||
Description = "Execute Unity Test Runner with advanced filtering options - exact test methods, regex patterns for classes/namespaces, assembly filtering"
|
||||
)]
|
||||
public class RunTestsTool : AbstractUnityTool<RunTestsSchema, RunTestsResponse>
|
||||
{
|
||||
public override string ToolName => McpConstants.TOOL_NAME_RUN_TESTS;
|
||||
|
||||
protected override async Task<RunTestsResponse> ExecuteAsync(RunTestsSchema parameters, CancellationToken ct)
|
||||
{
|
||||
// Create and execute RunTestsUseCase instance
|
||||
RunTestsUseCase useCase = new();
|
||||
return await useCase.ExecuteAsync(parameters, ct);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7287f0e369c642d3bb24494f1561b5b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86f9b7044f75e4de087ba50d53036889
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
name: uloop-run-tests
|
||||
description: "Run Unity Test Runner and report detailed results. Use for EditMode/PlayMode tests, change verification, or failure diagnosis."
|
||||
---
|
||||
|
||||
# uloop run-tests
|
||||
|
||||
Execute Unity Test Runner. This command requires the Unity Test Framework package (`com.unity.test-framework`). If that package is not installed, the command returns `Success: false` with an unsupported message and does not affect the other Unity CLI Loop tools.
|
||||
|
||||
When tests fail, NUnit XML results with error messages and stack traces are automatically saved. Read the XML file at `XmlPath` for detailed failure diagnosis.
|
||||
|
||||
Before executing tests, `uloop run-tests` checks for unsaved loaded Scene changes and unsaved current Prefab Stage changes. If any are found, it returns `Success: false`, keeps `TestCount` at `0`, lists the unsaved items in `Message`, and does not start the Unity Test Runner. Save or discard those editor changes, then rerun the command. Use `--save-before-run true` only when the user explicitly asks to save editor changes before continuing.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
uloop run-tests [options]
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `--test-mode` | string | `EditMode` | Test mode: `EditMode`, `PlayMode` |
|
||||
| `--filter-type` | string | `all` | Filter type: `all`, `exact`, `regex`, `assembly` |
|
||||
| `--filter-value` | string | - | Filter value (test name, pattern, or assembly) |
|
||||
| `--save-before-run` | boolean | `false` | Save unsaved loaded Scene changes and current Prefab Stage changes before running tests |
|
||||
|
||||
## Global Options
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--project-path <path>` | Optional. Use only when the target Unity project is not the current directory. |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Run all EditMode tests
|
||||
uloop run-tests
|
||||
|
||||
# Run PlayMode tests
|
||||
uloop run-tests --test-mode PlayMode
|
||||
|
||||
# Save explicitly approved editor changes before running tests
|
||||
uloop run-tests --save-before-run true
|
||||
|
||||
# Run specific test
|
||||
uloop run-tests --filter-type exact --filter-value "MyTest.TestMethod"
|
||||
|
||||
# Run tests matching pattern
|
||||
uloop run-tests --filter-type regex --filter-value ".*Integration.*"
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
Returns JSON with:
|
||||
- `Success` (boolean): Whether all tests passed
|
||||
- `Message` (string): Summary message
|
||||
- `CompletedAt` (string): ISO timestamp when the run finished
|
||||
- `TestCount` (number): Total tests executed
|
||||
- `PassedCount` (number): Passed tests
|
||||
- `FailedCount` (number): Failed tests
|
||||
- `SkippedCount` (number): Skipped tests
|
||||
- `XmlPath` (string | null): Path to NUnit XML result file. `null` when no XML was saved; populated only when tests failed and the XML file exists on disk.
|
||||
|
||||
### XML Result File
|
||||
|
||||
When tests fail, NUnit XML results are automatically saved to `{project_root}/.uloop/outputs/TestResults/<timestamp>.xml`. The XML contains per-test-case results including:
|
||||
- Test name and full name
|
||||
- Pass/fail/skip status and duration
|
||||
- For failed tests: `<message>` (assertion error) and `<stack-trace>`
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cae04d651537c45d6817556ccd093c39
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user