From 88f8ce447cd12b629fcfe5e61d80dcc0c8cab8ec Mon Sep 17 00:00:00 2001 From: youssef-backport-bot Date: Wed, 19 Feb 2025 10:09:17 +0100 Subject: [PATCH] [rel/3.8] Fix ClassCleanup not called when the first test in class is ignored (#5071) Co-authored-by: Youssef1313 --- .../MSTest.TestAdapter/Execution/TestClassInfo.cs | 1 + .../MSTest.TestAdapter/Execution/UnitTestRunner.cs | 5 +++-- .../MSTest.Acceptance.IntegrationTests/IgnoreTests.cs | 9 ++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index ad25be8320..bae6d87596 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -617,6 +617,7 @@ TestResult DoRun() // If ClassInitialize method has not been executed, then we should not execute ClassCleanup // Note that if there is no ClassInitialze method at all, we will still set // IsClassInitializeExecuted to true in RunClassInitialize + // IsClassInitializeExecuted can be false if all tests in the class are ignored. || !IsClassInitializeExecuted) { return null; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs index be00ad50a9..b7ea5ffa6b 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs @@ -211,10 +211,11 @@ internal async Task RunSingleTestAsync(TestMethod testMethod, IDic } } + ITestContext testContextForClassCleanup = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties, messageLogger, testContextForTestExecution.Context.CurrentTestOutcome); + testMethodInfo?.Parent.RunClassCleanup(testContextForClassCleanup, _classCleanupManager, testMethodInfo, testMethod, result); + if (testMethodInfo?.Parent.Parent.IsAssemblyInitializeExecuted == true) { - ITestContext testContextForClassCleanup = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties, messageLogger, testContextForTestExecution.Context.CurrentTestOutcome); - testMethodInfo.Parent.RunClassCleanup(testContextForClassCleanup, _classCleanupManager, testMethodInfo, testMethod, result); ITestContext testContextForAssemblyCleanup = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties, messageLogger, testContextForClassCleanup.Context.CurrentTestOutcome); RunAssemblyCleanupIfNeeded(testContextForAssemblyCleanup, _classCleanupManager, _typeCache, result); } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs index 2dd11219bc..7edc370183 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs @@ -18,9 +18,11 @@ public async Task ClassCleanup_Inheritance_WhenClassIsSkipped() // Assert testHostResult.AssertExitCodeIs(ExitCodes.Success); - testHostResult.AssertOutputContainsSummary(failed: 0, passed: 11, skipped: 7); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 11, skipped: 8); testHostResult.AssertOutputContains("SubClass.Method"); + testHostResult.AssertOutputContains("SubClass.ClassCleanup"); + testHostResult.AssertOutputDoesNotContain("SubClass.IgnoredMethod"); } [TestMethod] @@ -191,6 +193,11 @@ public class SubClass : IntermediateClass public static void SubClassCleanup() => Console.WriteLine("SubClass.ClassCleanup"); + [TestMethod] + [Ignore] + public void IgnoredMethod() + => Console.WriteLine("SubClass.IgnoredMethod"); + [TestMethod] public void Method() => Console.WriteLine("SubClass.Method");