/// <summary> /// Executes all tests that start with the specified node /// </summary> /// <param name="vm">Test explorer view model</param> /// <param name="node">Root node of the subtree to run the tests for</param> /// <param name="token">Token to stop tests</param> public Task RunTestsFromNodeAsync(TestExplorerToolWindowViewModel vm, TestItemBase node, CancellationToken token) { TestRootItem rootToRun = null; switch (node) { case TestRootItem rootNode: // --- Prepare all file nodes to run rootNode.TestFilesToRun.Clear(); foreach (var child in rootNode.ChildItems) { if (!(child is TestFileItem fileItem)) { continue; } rootNode.TestFilesToRun.Add(fileItem); fileItem.CollectAllToRun(); } rootToRun = rootNode; break; case TestSetItem setNode: { // --- Prepare this test set to run setNode.TestsToRun.Clear(); setNode.CollectAllToRun(); var fileItem = setNode.Parent as TestFileItem; var root = rootToRun = fileItem.Parent as TestRootItem; root.TestFilesToRun.Clear(); root.TestFilesToRun.Add(fileItem); fileItem.TestSetsToRun.Clear(); fileItem.TestSetsToRun.Add(setNode); break; } case TestItem testNode: { // --- Prepare this test to run testNode.TestCasesToRun.Clear(); testNode.CollectAllToRun(); var setItem = testNode.Parent as TestSetItem; var fileItem = setItem.Parent as TestFileItem; var root = rootToRun = fileItem.Parent as TestRootItem; root.TestFilesToRun.Clear(); root.TestFilesToRun.Add(fileItem); fileItem.TestSetsToRun.Clear(); fileItem.TestSetsToRun.Add(setItem); setItem.TestsToRun.Clear(); setItem.TestsToRun.Add(testNode); break; } case TestCaseItem caseNode: { // --- Prepare this test case to run var testItem = caseNode.Parent as TestItem; var setItem = testItem.Parent as TestSetItem; var fileItem = setItem?.Parent as TestFileItem; var root = rootToRun = fileItem.Parent as TestRootItem; root.TestFilesToRun.Clear(); root.TestFilesToRun.Add(fileItem); fileItem.TestSetsToRun.Clear(); fileItem.TestSetsToRun.Add(setItem); setItem.TestsToRun.Clear(); setItem.TestsToRun.Add(testItem); testItem.TestCasesToRun.Clear(); testItem.TestCasesToRun.Add(caseNode); break; } } return(rootToRun != null ? ExecuteTestTreeAsync(vm, rootToRun, token) : Task.FromResult(0)); }
/// <summary> /// Execute all test held by the specified root node /// </summary> /// <param name="vm">Test explorer view model</param> /// <param name="rootToRun">Root node instance</param> /// <param name="token">Token to cancel tests</param> private async Task ExecuteTestTreeAsync(TestExplorerToolWindowViewModel vm, TestRootItem rootToRun, CancellationToken token) { if (token.IsCancellationRequested) { return; } // --- Init running tests vm.TestRoot.SubTreeForEach(item => item.LogItems.Clear()); vm.TestRoot.Log("Test execution started"); // --- Start running tests var watch = new Stopwatch(); watch.Start(); rootToRun.State = TestState.Running; try { // --- Run each test file foreach (var fileToRun in rootToRun.TestFilesToRun) { if (token.IsCancellationRequested) { return; } fileToRun.State = TestState.Running; SetTestRootState(rootToRun); await ExecuteFileTests(vm, fileToRun, token); SetTestRootState(rootToRun); vm.UpdateCounters(); } } catch (Exception ex) { HandleException(rootToRun, ex); } finally { watch.Stop(); // --- Mark inconclusive nodes rootToRun.TestFilesToRun.ForEach(i => { if (i.State == TestState.NotRun) { SetSubTreeState(i, TestState.Inconclusive); } }); SetTestRootState(rootToRun); // --- Report outcome details vm.UpdateCounters(); ReportEllapsedTime("Tests", vm.TestRoot, watch); if (token.IsCancellationRequested) { vm.TestRoot.Log("Test run has been cancelled by the user.", LogEntryType.Fail); } if (vm.Counters.Success == 1) { vm.TestRoot.Log("1 test successfully ran.", LogEntryType.Success); } else if (vm.Counters.Success > 1) { vm.TestRoot.Log($"{vm.Counters.Success} tests successfully ran.", LogEntryType.Success); } if (vm.Counters.Failed == 1) { vm.TestRoot.Log("1 test failed.", LogEntryType.Fail); } else if (vm.Counters.Failed > 1) { vm.TestRoot.Log($"{vm.Counters.Failed} tests failed.", LogEntryType.Fail); } if (vm.Counters.Aborted > 0 || vm.Counters.Inconclusive > 0) { vm.TestRoot.Log("The test result is inconclusive.", LogEntryType.Fail); } } }
/// <summary> /// Set the state of the test root node according to its files' state /// </summary> /// <param name="rootToRun">Root node</param> private static void SetTestRootState(TestRootItem rootToRun) { SetTestItemState(rootToRun, rootToRun.TestFilesToRun); }