Skip to content

Commit 347ccf7

Browse files
committed
# Conflicts: # Editor/Services/TestRunnerService.cs
2 parents 0ae447c + 10be316 commit 347ccf7

File tree

5 files changed

+45
-28
lines changed

5 files changed

+45
-28
lines changed

Editor/Services/ITestRunnerService.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ public interface ITestRunnerService
2222
/// </summary>
2323
/// <param name="testMode">The test mode to run (EditMode or PlayMode).</param>
2424
/// <param name="returnOnlyFailures">If true, only failed test results are included in the output.</param>
25+
/// <param name="returnWithLogs">If true, all logs are included in the output.</param>
2526
/// <param name="testFilter">A filter string to select specific tests to run.</param>
2627
/// <returns>Task that resolves with test results when tests are complete</returns>
27-
Task<JObject> ExecuteTestsAsync(TestMode testMode, bool returnOnlyFailures, string testFilter);
28+
Task<JObject> ExecuteTestsAsync(TestMode testMode, bool returnOnlyFailures, bool returnWithLogs, string testFilter);
2829
}
29-
}
30+
}

Editor/Services/TestRunnerService.cs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class TestRunnerService : ITestRunnerService, ICallbacks
2121
private readonly TestRunnerApi _testRunnerApi;
2222
private TaskCompletionSource<JObject> _tcs;
2323
private bool _returnOnlyFailures;
24+
private bool _returnWithLogs;
2425
private List<ITestResultAdaptor> _results;
2526

2627
/// <summary>
@@ -77,13 +78,15 @@ public async Task<List<ITestAdaptor>> GetAllTestsAsync(string testModeFilter = "
7778
/// </summary>
7879
/// <param name="testMode">The test mode to run (EditMode or PlayMode).</param>
7980
/// <param name="returnOnlyFailures">If true, only failed test results are included in the output.</param>
81+
/// <param name="returnWithLogs">If true, all logs are included in the output.</param>
8082
/// <param name="testFilter">A filter string to select specific tests to run.</param>
8183
/// <returns>Task that resolves with test results when tests are complete</returns>
82-
public async Task<JObject> ExecuteTestsAsync(TestMode testMode, bool returnOnlyFailures, string testFilter = "")
84+
public async Task<JObject> ExecuteTestsAsync(TestMode testMode, bool returnOnlyFailures, bool returnWithLogs, string testFilter = "")
8385
{
8486
_tcs = new TaskCompletionSource<JObject>();
8587
_results = new List<ITestResultAdaptor>();
8688
_returnOnlyFailures = returnOnlyFailures;
89+
_returnWithLogs = returnWithLogs;
8790
var filter = new Filter { testMode = testMode };
8891

8992
if (!string.IsNullOrEmpty(testFilter))
@@ -142,6 +145,9 @@ private void CollectTestItems(ITestAdaptor testAdaptor, List<ITestAdaptor> tests
142145
/// </summary>
143146
public void RunStarted(ITestAdaptor testsToRun)
144147
{
148+
if (_tcs == null)
149+
return;
150+
145151
McpLogger.LogInfo($"Test run started: {testsToRun?.Name}");
146152
}
147153

@@ -158,17 +164,23 @@ public void TestStarted(ITestAdaptor test)
158164
/// </summary>
159165
public void TestFinished(ITestResultAdaptor result)
160166
{
161-
if (result != null) // Add null check
162-
_results.Add(result);
167+
if (_tcs == null)
168+
return;
169+
170+
_results.Add(result);
163171
}
164172

165173
/// <summary>
166174
/// Called when the test run finishes.
167175
/// </summary>
168176
public void RunFinished(ITestResultAdaptor result)
169177
{
178+
if (_tcs == null)
179+
return;
180+
170181
var summary = BuildResultJson(_results, result);
171-
_tcs?.TrySetResult(summary);
182+
_tcs.TrySetResult(summary);
183+
_tcs = null;
172184
}
173185

174186
#endregion
@@ -192,32 +204,30 @@ private async Task<JObject> WaitForCompletionAsync(int timeoutSeconds)
192204

193205
private JObject BuildResultJson(List<ITestResultAdaptor> results, ITestResultAdaptor result)
194206
{
195-
int pass = results.Count(r => r.ResultState == "Passed");
196-
int fail = results.Count(r => r.ResultState == "Failed");
197-
int skip = results.Count(r => r.ResultState == "Skipped");
198-
string state = result != null ? result.ResultState : "Unknown";
199-
double duration = result != null ? result.Duration : -1;
200-
201207
var arr = new JArray(results
208+
.Where(r => !r.HasChildren)
202209
.Where(r => !_returnOnlyFailures || r.ResultState == "Failed")
203210
.Select(r => new JObject {
204211
["name"] = r.Name,
205212
["fullName"] = r.FullName,
206213
["state"] = r.ResultState,
207214
["message"] = r.Message,
208-
["duration"] = r.Duration
215+
["duration"] = r.Duration,
216+
["logs"] = _returnWithLogs ? r.Output : null,
217+
["stackTrace"] = r.StackTrace
209218
}));
210219

220+
int testCount = result.PassCount + result.SkipCount + result.FailCount;
211221
return new JObject {
212222
["success"] = true,
213223
["type"] = "text",
214-
["message"] = $"{result.Test.Name} test run completed: {pass}/{results.Count} passed - {fail}/{results.Count} failed - {skip}/{results.Count} skipped",
215-
["resultState"] = state,
216-
["durationSeconds"] = duration,
224+
["message"] = $"{result.Test.Name} test run completed: {result.PassCount}/{testCount} passed - {result.FailCount}/{testCount} failed - {result.SkipCount}/{testCount} skipped",
225+
["resultState"] = result.ResultState,
226+
["durationSeconds"] = result.Duration,
217227
["testCount"] = results.Count,
218-
["passCount"] = pass,
219-
["failCount"] = fail,
220-
["skipCount"] = skip,
228+
["passCount"] = result.PassCount,
229+
["failCount"] = result.FailCount,
230+
["skipCount"] = result.SkipCount,
221231
["results"] = arr
222232
};
223233
}

Editor/Tools/RunTestsTool.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public override async void ExecuteAsync(JObject parameters, TaskCompletionSource
3737
string testModeStr = parameters?["testMode"]?.ToObject<string>() ?? "EditMode";
3838
string testFilter = parameters?["testFilter"]?.ToObject<string>(); // Optional
3939
bool returnOnlyFailures = parameters?["returnOnlyFailures"]?.ToObject<bool>() ?? false; // Optional
40+
bool returnWithLogs = parameters?["returnWithLogs"]?.ToObject<bool>() ?? false; // Optional
4041

4142
TestMode testMode = TestMode.EditMode;
4243

@@ -48,7 +49,7 @@ public override async void ExecuteAsync(JObject parameters, TaskCompletionSource
4849
McpLogger.LogInfo($"Executing RunTestsTool: Mode={testMode}, Filter={testFilter ?? "(none)"}");
4950

5051
// Call the service to run tests
51-
JObject result = await _testRunnerService.ExecuteTestsAsync(testMode, returnOnlyFailures, testFilter);
52+
JObject result = await _testRunnerService.ExecuteTestsAsync(testMode, returnOnlyFailures, returnWithLogs, testFilter);
5253
tcs.SetResult(result);
5354
}
5455
}

Server~/build/tools/runTestsTool.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ const toolName = 'run_tests';
55
const toolDescription = 'Runs Unity\'s Test Runner tests';
66
const paramsSchema = z.object({
77
testMode: z.string().optional().default('EditMode').describe('The test mode to run (EditMode or PlayMode) - defaults to EditMode (optional)'),
8-
testFilter: z.string().optional().default('').describe('The specific test filter to run (e.g. specific test name or namespace) (optional)'),
9-
returnOnlyFailures: z.boolean().optional().default(true).describe('Whether to show only failed tests in the results (optional)')
8+
testFilter: z.string().optional().default('').describe('The specific test filter to run (e.g. specific test name or class name, must include namespace) (optional)'),
9+
returnOnlyFailures: z.boolean().optional().default(true).describe('Whether to show only failed tests in the results (optional)'),
10+
returnWithLogs: z.boolean().optional().default(false).describe('Whether to return the test logs in the results (optional)')
1011
});
1112
/**
1213
* Creates and registers the Run Tests tool with the MCP server
@@ -41,14 +42,15 @@ export function registerRunTestsTool(server, mcpUnity, logger) {
4142
* @throws McpUnityError if the request to Unity fails
4243
*/
4344
async function toolHandler(mcpUnity, params = {}) {
44-
const { testMode = 'EditMode', testFilter = '', returnOnlyFailures = true } = params;
45+
const { testMode = 'EditMode', testFilter = '', returnOnlyFailures = true, returnWithLogs = false } = params;
4546
// Create and wait for the test run
4647
const response = await mcpUnity.sendRequest({
4748
method: toolName,
4849
params: {
4950
testMode,
5051
testFilter,
51-
returnOnlyFailures
52+
returnOnlyFailures,
53+
returnWithLogs
5254
}
5355
});
5456
// Process the test results

Server~/src/tools/runTestsTool.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ const toolName = 'run_tests';
1010
const toolDescription = 'Runs Unity\'s Test Runner tests';
1111
const paramsSchema = z.object({
1212
testMode: z.string().optional().default('EditMode').describe('The test mode to run (EditMode or PlayMode) - defaults to EditMode (optional)'),
13-
testFilter: z.string().optional().default('').describe('The specific test filter to run (e.g. specific test name or namespace) (optional)'),
14-
returnOnlyFailures: z.boolean().optional().default(true).describe('Whether to show only failed tests in the results (optional)')
13+
testFilter: z.string().optional().default('').describe('The specific test filter to run (e.g. specific test name or class name, must include namespace) (optional)'),
14+
returnOnlyFailures: z.boolean().optional().default(true).describe('Whether to show only failed tests in the results (optional)'),
15+
returnWithLogs: z.boolean().optional().default(false).describe('Whether to return the test logs in the results (optional)')
1516
});
1617

1718
/**
@@ -56,7 +57,8 @@ async function toolHandler(mcpUnity: McpUnity, params: any = {}): Promise<CallTo
5657
const {
5758
testMode = 'EditMode',
5859
testFilter = '',
59-
returnOnlyFailures = true
60+
returnOnlyFailures = true,
61+
returnWithLogs = false
6062
} = params;
6163

6264
// Create and wait for the test run
@@ -65,7 +67,8 @@ async function toolHandler(mcpUnity: McpUnity, params: any = {}): Promise<CallTo
6567
params: {
6668
testMode,
6769
testFilter,
68-
returnOnlyFailures
70+
returnOnlyFailures,
71+
returnWithLogs
6972
}
7073
});
7174

0 commit comments

Comments
 (0)