From 584830496bda2a02258d180179c4d73201bbeb9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sun, 29 Dec 2024 11:00:34 +0100 Subject: [PATCH 1/2] Refactor running of data driven tests --- .../Execution/TestMethodRunner.cs | 168 +++++++++--------- 1 file changed, 88 insertions(+), 80 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index a3ee59fa98..6f768e65f4 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -172,7 +172,11 @@ internal UnitTestResult[] RunTestMethod() TestResult[] testResults = ExecuteTestWithDataSource(null, data); results.AddRange(testResults); } - else if (ExecuteDataSourceBasedTests(results)) + else if (TryExecuteDataSourceBasedTests(results)) + { + isDataDriven = true; + } + else if (TryExecuteFoldedDataDrivenTests(results)) { isDataDriven = true; } @@ -243,108 +247,112 @@ internal UnitTestResult[] RunTestMethod() return results.ToUnitTestResults(); } - private bool ExecuteDataSourceBasedTests(List results) + private bool TryExecuteDataSourceBasedTests(List results) { - bool isDataDriven = false; - DataSourceAttribute[] dataSourceAttribute = _testMethodInfo.GetAttributes(false); if (dataSourceAttribute is { Length: 1 }) { - isDataDriven = true; - Stopwatch watch = new(); - watch.Start(); + ExecuteTestFromDataSourceAttribute(results); + return true; + } - try - { - IEnumerable? dataRows = PlatformServiceProvider.Instance.TestDataSource.GetData(_testMethodInfo, _testContext); + return false; + } + + private bool TryExecuteFoldedDataDrivenTests(List results) + { + IEnumerable? testDataSources = _testMethodInfo.GetAttributes(false)?.OfType(); + if (testDataSources?.Any() != true) + { + return false; + } + + foreach (UTF.ITestDataSource testDataSource in testDataSources) + { + IEnumerable? dataSource; - if (dataRows == null) + // This code is to execute tests. To discover the tests code is in AssemblyEnumerator.ProcessTestDataSourceTests. + // Any change made here should be reflected in AssemblyEnumerator.ProcessTestDataSourceTests as well. + dataSource = testDataSource.GetData(_testMethodInfo.MethodInfo); + + if (!dataSource.Any()) + { + if (!MSTestSettings.CurrentSettings.ConsiderEmptyDataSourceAsInconclusive) { - var inconclusiveResult = new TestResult - { - Outcome = UTF.UnitTestOutcome.Inconclusive, - Duration = watch.Elapsed, - }; - results.Add(inconclusiveResult); + throw testDataSource.GetExceptionForEmptyDataSource(_testMethodInfo.MethodInfo); } - else + + var inconclusiveResult = new TestResult { - try - { - int rowIndex = 0; + Outcome = UTF.UnitTestOutcome.Inconclusive, + }; + results.Add(inconclusiveResult); + continue; + } - foreach (object dataRow in dataRows) - { - TestResult[] testResults = ExecuteTestWithDataRow(dataRow, rowIndex++); - results.AddRange(testResults); - } - } - finally - { - _testContext.SetDataConnection(null); - _testContext.SetDataRow(null); - } + foreach (object?[] data in dataSource) + { + try + { + TestResult[] testResults = ExecuteTestWithDataSource(testDataSource, data); + + results.AddRange(testResults); + } + finally + { + _testMethodInfo.SetArguments(null); } } - catch (Exception ex) + } + + return true; + } + + private void ExecuteTestFromDataSourceAttribute(List results) + { + Stopwatch watch = new(); + watch.Start(); + + try + { + IEnumerable? dataRows = PlatformServiceProvider.Instance.TestDataSource.GetData(_testMethodInfo, _testContext); + if (dataRows == null) { - var failedResult = new TestResult + var inconclusiveResult = new TestResult { - Outcome = UTF.UnitTestOutcome.Error, - TestFailureException = ex, + Outcome = UTF.UnitTestOutcome.Inconclusive, Duration = watch.Elapsed, }; - results.Add(failedResult); + results.Add(inconclusiveResult); + return; } - } - else - { - IEnumerable? testDataSources = _testMethodInfo.GetAttributes(false)?.OfType(); - if (testDataSources != null) + try { - foreach (UTF.ITestDataSource testDataSource in testDataSources) - { - isDataDriven = true; - IEnumerable? dataSource; - - // This code is to execute tests. To discover the tests code is in AssemblyEnumerator.ProcessTestDataSourceTests. - // Any change made here should be reflected in AssemblyEnumerator.ProcessTestDataSourceTests as well. - dataSource = testDataSource.GetData(_testMethodInfo.MethodInfo); + int rowIndex = 0; - if (!dataSource.Any()) - { - if (!MSTestSettings.CurrentSettings.ConsiderEmptyDataSourceAsInconclusive) - { - throw testDataSource.GetExceptionForEmptyDataSource(_testMethodInfo.MethodInfo); - } - - var inconclusiveResult = new TestResult - { - Outcome = UTF.UnitTestOutcome.Inconclusive, - }; - results.Add(inconclusiveResult); - continue; - } - - foreach (object?[] data in dataSource) - { - try - { - TestResult[] testResults = ExecuteTestWithDataSource(testDataSource, data); - - results.AddRange(testResults); - } - finally - { - _testMethodInfo.SetArguments(null); - } - } + foreach (object dataRow in dataRows) + { + TestResult[] testResults = ExecuteTestWithDataRow(dataRow, rowIndex++); + results.AddRange(testResults); } } + finally + { + _testContext.SetDataConnection(null); + _testContext.SetDataRow(null); + } + } + catch (Exception ex) + { + var failedResult = new TestResult + { + Outcome = UTF.UnitTestOutcome.Error, + TestFailureException = ex, + Duration = watch.Elapsed, + }; + results.Add(failedResult); } - - return isDataDriven; } private TestResult[] ExecuteTestWithDataSource(UTF.ITestDataSource? testDataSource, object?[]? data) From ffefa02d052c2a380e823f776952d196951a33ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sun, 29 Dec 2024 11:19:54 +0100 Subject: [PATCH 2/2] More refactoring --- .../Execution/TestMethodRunner.cs | 77 ++++++++++--------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index 6f768e65f4..562bb7376e 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -161,47 +161,54 @@ internal UnitTestResult[] RunTestMethod() DebugEx.Assert(_testMethodInfo.TestMethod != null, "Test method should not be null."); List results = []; - bool isDataDriven = false; - var parentStopwatch = Stopwatch.StartNew(); - - if (_testMethodInfo.TestMethodOptions.Executor != null) + if (_testMethodInfo.TestMethodOptions.Executor == null) { - if (_test.DataType == DynamicDataType.ITestDataSource) - { - object?[]? data = DataSerializationHelper.Deserialize(_test.SerializedData); - TestResult[] testResults = ExecuteTestWithDataSource(null, data); - results.AddRange(testResults); - } - else if (TryExecuteDataSourceBasedTests(results)) - { - isDataDriven = true; - } - else if (TryExecuteFoldedDataDrivenTests(results)) - { - isDataDriven = true; - } - else + PlatformServiceProvider.Instance.AdapterTraceLogger.LogError( + "Not able to get executor for method {0}.{1}", + _testMethodInfo.TestClassName, + _testMethodInfo.TestMethodName); + + TestResult emptyResult = new() { - _testContext.SetDisplayName(_test.DisplayName); - TestResult[] testResults = ExecuteTest(_testMethodInfo); + Outcome = UTF.UnitTestOutcome.Unknown, + TestFailureException = new TestFailedException(UnitTestOutcome.Error, Resource.UTA_NoTestResult), + }; + _testContext.SetOutcome(emptyResult.Outcome); - foreach (TestResult testResult in testResults) - { - if (StringEx.IsNullOrWhiteSpace(testResult.DisplayName)) - { - testResult.DisplayName = _test.DisplayName; - } - } + results.Add(emptyResult); + return results.ToUnitTestResults(); + } - results.AddRange(testResults); - } + bool isDataDriven = false; + var parentStopwatch = Stopwatch.StartNew(); + if (_test.DataType == DynamicDataType.ITestDataSource) + { + object?[]? data = DataSerializationHelper.Deserialize(_test.SerializedData); + TestResult[] testResults = ExecuteTestWithDataSource(null, data); + results.AddRange(testResults); + } + else if (TryExecuteDataSourceBasedTests(results)) + { + isDataDriven = true; + } + else if (TryExecuteFoldedDataDrivenTests(results)) + { + isDataDriven = true; } else { - PlatformServiceProvider.Instance.AdapterTraceLogger.LogError( - "Not able to get executor for method {0}.{1}", - _testMethodInfo.TestClassName, - _testMethodInfo.TestMethodName); + _testContext.SetDisplayName(_test.DisplayName); + TestResult[] testResults = ExecuteTest(_testMethodInfo); + + foreach (TestResult testResult in testResults) + { + if (StringEx.IsNullOrWhiteSpace(testResult.DisplayName)) + { + testResult.DisplayName = _test.DisplayName; + } + } + + results.AddRange(testResults); } // Get aggregate outcome. @@ -214,6 +221,7 @@ internal UnitTestResult[] RunTestMethod() // In legacy scenario #pragma warning disable CS0618 // Type or member is obsolete if (_test.TestIdGenerationStrategy == TestIdGenerationStrategy.Legacy) +#pragma warning restore CS0618 // Type or member is obsolete { parentStopwatch.Stop(); var parentResult = new TestResult @@ -225,7 +233,6 @@ internal UnitTestResult[] RunTestMethod() results = UpdateResultsWithParentInfo(results, parentResult); } -#pragma warning restore CS0618 // Type or member is obsolete else { results = UpdateResultsWithParentInfo(results);