diff --git a/src/Adapter/MSTest.CoreAdapter/Execution/TestAssemblyInfo.cs b/src/Adapter/MSTest.CoreAdapter/Execution/TestAssemblyInfo.cs index ca3ff03b9c..92ae48d11a 100644 --- a/src/Adapter/MSTest.CoreAdapter/Execution/TestAssemblyInfo.cs +++ b/src/Adapter/MSTest.CoreAdapter/Execution/TestAssemblyInfo.cs @@ -169,25 +169,22 @@ public void RunAssemblyInitialize(TestContext testContext) throw this.AssemblyInitializationException; } - var realException = this.AssemblyInitializationException.InnerException - ?? this.AssemblyInitializationException; - - var outcome = UnitTestOutcome.Failed; - if (!realException.TryGetUnitTestAssertException(out outcome, out var errorMessage, out var stackTraceInfo)) - { - var exception = realException.GetType().ToString(); - var message = StackTraceHelper.GetExceptionMessage(realException); - errorMessage = string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_AssemblyInitMethodThrows, - this.AssemblyInitializeMethod.DeclaringType.FullName, - this.AssemblyInitializeMethod.Name, - exception, - message); - stackTraceInfo = StackTraceHelper.GetStackTraceInformation(realException); - } - - var testFailedException = new TestFailedException(outcome, errorMessage, stackTraceInfo); + var realException = this.AssemblyInitializationException.InnerException ?? this.AssemblyInitializationException; + + var outcome = realException is AssertInconclusiveException ? UnitTestOutcome.Inconclusive : UnitTestOutcome.Failed; + + // Do not use StackTraceHelper.GetExceptionMessage(realException) as it prefixes the message with the exception type name. + var exceptionMessage = realException.TryGetMessage(); + var errorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_AssemblyInitMethodThrows, + this.AssemblyInitializeMethod.DeclaringType.FullName, + this.AssemblyInitializeMethod.Name, + realException.GetType().ToString(), + exceptionMessage); + var exceptionStackTraceInfo = StackTraceHelper.GetStackTraceInformation(realException); + + var testFailedException = new TestFailedException(outcome, errorMessage, exceptionStackTraceInfo, realException); this.AssemblyInitializationException = testFailedException; throw testFailedException; @@ -243,4 +240,4 @@ public string RunAssemblyCleanup() } } } -} \ No newline at end of file +} diff --git a/src/Adapter/MSTest.CoreAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.CoreAdapter/Execution/TestClassInfo.cs index 985dc3f359..23c3e82a65 100644 --- a/src/Adapter/MSTest.CoreAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.CoreAdapter/Execution/TestClassInfo.cs @@ -10,10 +10,12 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution using System.Globalization; using System.Linq; using System.Reflection; + using Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; using ObjectModel; - using UnitTestOutcome = Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestOutcome; + + using ObjectModelUnitTestOutcome = ObjectModel.UnitTestOutcome; /// /// Defines the TestClassInfo object @@ -319,21 +321,20 @@ public void RunClassInitialize(TestContext testContext) // Fail the current test if it was a failure. var realException = this.ClassInitializationException.InnerException ?? this.ClassInitializationException; - var outcome = UnitTestOutcome.Failed; - if (!realException.TryGetUnitTestAssertException(out outcome, out string errorMessage, out StackTraceInformation exceptionStackTraceInfo)) - { - errorMessage = string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_ClassInitMethodThrows, - this.ClassType.FullName, - failedClassInitializeMethodName, - realException.GetType().ToString(), - StackTraceHelper.GetExceptionMessage(realException)); - - exceptionStackTraceInfo = realException.TryGetStackTraceInformation(); - } + var outcome = realException is AssertInconclusiveException ? ObjectModelUnitTestOutcome.Inconclusive : ObjectModelUnitTestOutcome.Failed; + + // Do not use StackTraceHelper.GetExceptionMessage(realException) as it prefixes the message with the exception type name. + var exceptionMessage = realException.TryGetMessage(); + var errorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_ClassInitMethodThrows, + this.ClassType.FullName, + failedClassInitializeMethodName, + realException.GetType().ToString(), + exceptionMessage); + var exceptionStackTraceInfo = StackTraceHelper.GetStackTraceInformation(realException); - var testFailedException = new TestFailedException(outcome, errorMessage, exceptionStackTraceInfo); + var testFailedException = new TestFailedException(outcome, errorMessage, exceptionStackTraceInfo, realException); this.ClassInitializationException = testFailedException; throw testFailedException; @@ -411,7 +412,7 @@ public string RunClassCleanup(ClassCleanupBehavior classCleanupLifecycle = Class if (classCleanupLifecycle == ClassCleanupBehavior.EndOfClass) { - var testFailedException = new TestFailedException(UnitTestOutcome.Failed, errorMessage, exceptionStackTraceInfo); + var testFailedException = new TestFailedException(ObjectModelUnitTestOutcome.Failed, errorMessage, exceptionStackTraceInfo); this.ClassCleanupException = testFailedException; throw testFailedException; } @@ -425,4 +426,4 @@ public string RunClassCleanup(ClassCleanupBehavior classCleanupLifecycle = Class return null; } } -} \ No newline at end of file +} diff --git a/src/Adapter/MSTest.CoreAdapter/Execution/TestMethodInfo.cs b/src/Adapter/MSTest.CoreAdapter/Execution/TestMethodInfo.cs index 08cd44d35f..c43a8f6ca4 100644 --- a/src/Adapter/MSTest.CoreAdapter/Execution/TestMethodInfo.cs +++ b/src/Adapter/MSTest.CoreAdapter/Execution/TestMethodInfo.cs @@ -17,7 +17,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; - using UnitTestOutcome = Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestOutcome; + using ObjectModelUnitTestOutcome = Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestOutcome; using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -317,7 +317,7 @@ private TestResult ExecuteInternal(object[] arguments) if (hasTestInitializePassed && !isExceptionThrown && this.TestMethodOptions.ExpectedException != null) { result.TestFailureException = new TestFailedException( - UnitTestOutcome.Failed, + ObjectModelUnitTestOutcome.Failed, this.TestMethodOptions.ExpectedException.NoExceptionMessage); result.Outcome = TestTools.UnitTesting.UnitTestOutcome.Failed; } @@ -385,9 +385,11 @@ private bool IsExpectedException(Exception ex, TestResult result) // attribute's Verify method) is an AssertInconclusiveException. If so, set // the test outcome to Inconclusive. result.TestFailureException = new TestFailedException( - exceptionFromVerify is UTF.AssertInconclusiveException ? UnitTestOutcome.Inconclusive : UnitTestOutcome.Failed, - exceptionFromVerify.TryGetMessage(), - realException.TryGetStackTraceInformation()); + exceptionFromVerify is UTF.AssertInconclusiveException + ? ObjectModelUnitTestOutcome.Inconclusive + : ObjectModelUnitTestOutcome.Failed, + exceptionFromVerify.TryGetMessage(), + realException.TryGetStackTraceInformation()); return false; } else @@ -428,7 +430,7 @@ private Exception HandleMethodException(Exception ex, string className, string m if (isTargetInvocationException && ex.InnerException == null) { var errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_FailedToGetTestMethodException, className, methodName); - return new TestFailedException(UnitTestOutcome.Error, errorMessage); + return new TestFailedException(ObjectModelUnitTestOutcome.Error, errorMessage); } // Get the real exception thrown by the test method @@ -441,24 +443,17 @@ private Exception HandleMethodException(Exception ex, string className, string m } else { - string errorMessage; + string errorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_TestMethodThrows, + className, + methodName, + StackTraceHelper.GetExceptionMessage(realException)); // Handle special case of UI objects in TestMethod to suggest UITestMethod if (realException.HResult == -2147417842) { - errorMessage = string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_WrongThread, - string.Format(CultureInfo.CurrentCulture, Resource.UTA_TestMethodThrows, className, methodName, StackTraceHelper.GetExceptionMessage(realException))); - } - else - { - errorMessage = string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_TestMethodThrows, - className, - methodName, - StackTraceHelper.GetExceptionMessage(realException)); + errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_WrongThread, errorMessage); } StackTraceInformation stackTrace = null; @@ -472,7 +467,7 @@ private Exception HandleMethodException(Exception ex, string className, string m stackTrace = StackTraceHelper.GetStackTraceInformation(realException); } - return new TestFailedException(UnitTestOutcome.Failed, errorMessage, stackTrace, realException); + return new TestFailedException(ObjectModelUnitTestOutcome.Failed, errorMessage, stackTrace, realException); } } @@ -509,70 +504,66 @@ private void RunTestCleanupMethod(object classInstance, TestResult result) } catch (Exception ex) { - var cleanupOutcome = UTF.UnitTestOutcome.Failed; var cleanupError = new StringBuilder(); var cleanupStackTrace = new StringBuilder(); - StackTraceInformation cleanupStackTraceInfo = null; - - TestFailedException testFailureException = result.TestFailureException as TestFailedException; - testFailureException.TryGetTestFailureExceptionMessageAndStackTrace(cleanupError, cleanupStackTrace); - - if (cleanupStackTrace.Length > 0) + if (result.TestFailureException is TestFailedException testFailureException) { - cleanupStackTrace.Append(Resource.UTA_CleanupStackTrace); - cleanupStackTrace.Append(Environment.NewLine); + if (!string.IsNullOrEmpty(testFailureException.Message)) + { + cleanupError.Append(testFailureException.Message); + cleanupError.AppendLine(); + } + + if (!string.IsNullOrEmpty(testFailureException.StackTraceInformation?.ErrorStackTrace)) + { + cleanupStackTrace.Append(testFailureException.StackTraceInformation.ErrorStackTrace); + cleanupStackTrace.Append(Environment.NewLine); + cleanupStackTrace.Append(Resource.UTA_CleanupStackTrace); + cleanupStackTrace.Append(Environment.NewLine); + } } Exception realException = ex.GetInnerExceptionOrDefault(); - // special case UnitTestAssertException to trim off part of the stack trace - if (!realException.TryGetUnitTestAssertException(out cleanupOutcome, out var exceptionMessage, out var realExceptionStackTraceInfo)) + if (testCleanupMethod != null) + { + // Do not use StackTraceHelper.GetExceptionMessage(realException) as it prefixes the message with the exception type name. + cleanupError.AppendFormat( + CultureInfo.CurrentCulture, + Resource.UTA_CleanupMethodThrows, + this.TestClassName, + testCleanupMethod.Name, + realException.GetType().ToString(), + realException.TryGetMessage()); + } + else { - cleanupOutcome = UTF.UnitTestOutcome.Failed; - exceptionMessage = this.GetTestCleanUpExceptionMessage(testCleanupMethod, realException); - realExceptionStackTraceInfo = realException.TryGetStackTraceInformation(); + // Use StackTraceHelper.GetExceptionMessage(realException) to get the message prefixed with the exception type name. + cleanupError.AppendFormat( + CultureInfo.CurrentCulture, + Resource.UTA_CleanupMethodThrowsGeneralError, + this.TestClassName, + StackTraceHelper.GetExceptionMessage(realException)); } - cleanupError.Append(exceptionMessage); + StackTraceInformation cleanupStackTraceInfo = null; + var realExceptionStackTraceInfo = realException.TryGetStackTraceInformation(); if (realExceptionStackTraceInfo != null) { cleanupStackTrace.Append(realExceptionStackTraceInfo.ErrorStackTrace); cleanupStackTraceInfo = cleanupStackTraceInfo ?? realExceptionStackTraceInfo; } - UTF.UnitTestOutcome outcome = testFailureException == null ? cleanupOutcome : cleanupOutcome.GetMoreImportantOutcome(result.Outcome); - StackTraceInformation finalStackTraceInfo = cleanupStackTraceInfo != null ? - new StackTraceInformation( - cleanupStackTrace.ToString(), - cleanupStackTraceInfo.ErrorFilePath, - cleanupStackTraceInfo.ErrorLineNumber, - cleanupStackTraceInfo.ErrorColumnNumber) : - new StackTraceInformation(cleanupStackTrace.ToString()); - - result.Outcome = outcome; - result.TestFailureException = new TestFailedException(outcome.ToUnitTestOutcome(), cleanupError.ToString(), finalStackTraceInfo); - } - } + var finalStackTraceInfo = cleanupStackTraceInfo != null + ? new StackTraceInformation( + cleanupStackTrace.ToString(), + cleanupStackTraceInfo.ErrorFilePath, + cleanupStackTraceInfo.ErrorLineNumber, + cleanupStackTraceInfo.ErrorColumnNumber) + : new StackTraceInformation(cleanupStackTrace.ToString()); - private string GetTestCleanUpExceptionMessage(MethodInfo testCleanupMethod, Exception exception) - { - if (testCleanupMethod != null) - { - return string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_CleanupMethodThrows, - this.TestClassName, - testCleanupMethod?.Name, - exception.GetType().ToString(), - StackTraceHelper.GetExceptionMessage(exception)); - } - else - { - return string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_CleanupMethodThrowsGeneralError, - this.TestClassName, - StackTraceHelper.GetExceptionMessage(exception)); + result.Outcome = result.Outcome.GetMoreImportantOutcome(realException is AssertInconclusiveException ? UTF.UnitTestOutcome.Inconclusive : UTF.UnitTestOutcome.Failed); + result.TestFailureException = new TestFailedException(result.Outcome.ToUnitTestOutcome(), cleanupError.ToString(), finalStackTraceInfo, realException); } } @@ -607,30 +598,26 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) } catch (Exception ex) { - var innerException = ex.GetInnerExceptionOrDefault(); - var outcome = TestTools.UnitTesting.UnitTestOutcome.Failed; + var realException = ex.GetInnerExceptionOrDefault(); - if (innerException.TryGetUnitTestAssertException(out outcome, out var exceptionMessage, out var exceptionStackTraceInfo)) - { - result.Outcome = outcome; - result.TestFailureException = new TestFailedException( - UnitTestOutcome.Failed, - exceptionMessage, - exceptionStackTraceInfo); - } - else - { - var stackTrace = StackTraceHelper.GetStackTraceInformation(innerException); - var errorMessage = string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_InitMethodThrows, - this.TestClassName, - testInitializeMethod?.Name, - StackTraceHelper.GetExceptionMessage(innerException)); + // Prefix the exception message with the exception type name as prefix when exception is not assert exception. + var exceptionMessage = realException is UnitTestAssertException + ? realException.TryGetMessage() + : StackTraceHelper.GetExceptionMessage(realException); + var errorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_InitMethodThrows, + this.TestClassName, + testInitializeMethod?.Name, + exceptionMessage); + var stackTrace = StackTraceHelper.GetStackTraceInformation(realException); - result.Outcome = TestTools.UnitTesting.UnitTestOutcome.Failed; - result.TestFailureException = new TestFailedException(UnitTestOutcome.Failed, errorMessage, stackTrace); - } + result.Outcome = realException is AssertInconclusiveException ? UTF.UnitTestOutcome.Inconclusive : UTF.UnitTestOutcome.Failed; + result.TestFailureException = new TestFailedException( + result.Outcome.ToUnitTestOutcome(), + errorMessage, + stackTrace, + realException); } return false; @@ -673,7 +660,7 @@ private bool SetTestContext(object classInstance, TestResult result) StackTraceHelper.GetExceptionMessage(ex.GetInnerExceptionOrDefault())); result.Outcome = TestTools.UnitTesting.UnitTestOutcome.Failed; - result.TestFailureException = new TestFailedException(UnitTestOutcome.Failed, errorMessage, stackTraceInfo); + result.TestFailureException = new TestFailedException(ObjectModelUnitTestOutcome.Failed, errorMessage, stackTraceInfo); } return false; @@ -727,7 +714,7 @@ private object CreateTestClassInstance(TestResult result) exceptionMessage); result.Outcome = TestTools.UnitTesting.UnitTestOutcome.Failed; - result.TestFailureException = new TestFailedException(UnitTestOutcome.Failed, errorMessage, stackTraceInfo); + result.TestFailureException = new TestFailedException(ObjectModelUnitTestOutcome.Failed, errorMessage, stackTraceInfo); } return classInstance; @@ -782,7 +769,7 @@ void executeAsyncAction() this.TestMethodOptions.TestContext.Context.CancellationTokenSource.Cancel(); } - TestResult timeoutResult = new TestResult() { Outcome = TestTools.UnitTesting.UnitTestOutcome.Timeout, TestFailureException = new TestFailedException(UnitTestOutcome.Timeout, errorMessage) }; + TestResult timeoutResult = new TestResult() { Outcome = TestTools.UnitTesting.UnitTestOutcome.Timeout, TestFailureException = new TestFailedException(ObjectModelUnitTestOutcome.Timeout, errorMessage) }; return timeoutResult; } } diff --git a/src/Adapter/MSTest.CoreAdapter/Extensions/ExceptionExtensions.cs b/src/Adapter/MSTest.CoreAdapter/Extensions/ExceptionExtensions.cs index f6e0b98b56..1a5196a036 100644 --- a/src/Adapter/MSTest.CoreAdapter/Extensions/ExceptionExtensions.cs +++ b/src/Adapter/MSTest.CoreAdapter/Extensions/ExceptionExtensions.cs @@ -85,57 +85,5 @@ internal static bool TryGetUnitTestAssertException(this Exception exception, out return false; } } - - /// - /// Checks whether exception is an Assert exception - /// - /// An instance. - /// Adapter's Outcome depending on type of assertion. - /// Exception message. - /// StackTraceInformation for the exception - /// True, if Assert exception. False, otherwise. - internal static bool TryGetUnitTestAssertException(this Exception exception, out UnitTestOutcome outcome, out string exceptionMessage, out StackTraceInformation exceptionStackTrace) - { - if (exception is UTF.UnitTestAssertException) - { - outcome = exception is UTF.AssertInconclusiveException ? - UnitTestOutcome.Inconclusive : UnitTestOutcome.Failed; - - exceptionMessage = exception.TryGetMessage(); - exceptionStackTrace = exception.TryGetStackTraceInformation(); - return true; - } - else - { - outcome = UnitTestOutcome.Failed; - exceptionMessage = null; - exceptionStackTrace = null; - return false; - } - } - - /// - /// Gets exception message and stack trace for TestFailedException. - /// - /// An instance. - /// Appends TestFailedException message to this message. - /// Appends TestFailedExeption stack trace to this stackTrace - internal static void TryGetTestFailureExceptionMessageAndStackTrace(this TestFailedException testFailureException, StringBuilder message, StringBuilder stackTrace) - { - if (testFailureException != null) - { - if (!string.IsNullOrEmpty(testFailureException.Message)) - { - message.Append(testFailureException.Message); - message.AppendLine(); - } - - if (testFailureException.StackTraceInformation != null && !string.IsNullOrEmpty(testFailureException.StackTraceInformation.ErrorStackTrace)) - { - stackTrace.Append(testFailureException.StackTraceInformation.ErrorStackTrace); - stackTrace.Append(Environment.NewLine); - } - } - } } } diff --git a/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestAssemblyInfoTests.cs b/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestAssemblyInfoTests.cs index 0d76fdc6e7..84342d6fd9 100644 --- a/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestAssemblyInfoTests.cs +++ b/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestAssemblyInfoTests.cs @@ -169,39 +169,45 @@ public void RunAssemblyInitializeShouldSetAssemblyInitializationExceptionOnExcep [TestMethod] public void RunAssemblyInitializeShouldThrowTestFailedExceptionOnAssertionFailure() { - DummyTestClass.AssemblyInitializeMethodBody = (tc) => UTF.Assert.Fail("Test failure"); + DummyTestClass.AssemblyInitializeMethodBody = tc => UTF.Assert.Fail("Test failure"); this.testAssemblyInfo.AssemblyInitializeMethod = typeof(DummyTestClass).GetMethod("AssemblyInitializeMethod"); var exception = ActionUtility.PerformActionAndReturnException(() => this.testAssemblyInfo.RunAssemblyInitialize(this.testContext)) as TestFailedException; Assert.IsNotNull(exception); Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); - StringAssert.Contains(exception.Message, "Test failure"); + Assert.AreEqual( + "Assembly Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestAssemblyInfoTests+DummyTestClass.AssemblyInitializeMethod threw exception. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Assert.Fail failed. Test failure. Aborting test execution.", + exception.Message); StringAssert.StartsWith( exception.StackTraceInformation.ErrorStackTrace, " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestAssemblyInfoTests.<>c."); + Assert.IsInstanceOfType(exception.InnerException, typeof(UTF.AssertFailedException)); } [TestMethod] public void RunAssemblyInitializeShouldThrowTestFailedExceptionWithInconclusiveOnAssertInconclusive() { - DummyTestClass.AssemblyInitializeMethodBody = (tc) => UTF.Assert.Inconclusive("Test Inconclusive"); + DummyTestClass.AssemblyInitializeMethodBody = tc => UTF.Assert.Inconclusive("Test Inconclusive"); this.testAssemblyInfo.AssemblyInitializeMethod = typeof(DummyTestClass).GetMethod("AssemblyInitializeMethod"); var exception = ActionUtility.PerformActionAndReturnException(() => this.testAssemblyInfo.RunAssemblyInitialize(this.testContext)) as TestFailedException; Assert.IsNotNull(exception); Assert.AreEqual(UnitTestOutcome.Inconclusive, exception.Outcome); - StringAssert.Contains(exception.Message, "Test Inconclusive"); + Assert.AreEqual( + "Assembly Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestAssemblyInfoTests+DummyTestClass.AssemblyInitializeMethod threw exception. Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException: Assert.Inconclusive failed. Test Inconclusive. Aborting test execution.", + exception.Message); StringAssert.StartsWith( exception.StackTraceInformation.ErrorStackTrace, " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestAssemblyInfoTests.<>c."); + Assert.IsInstanceOfType(exception.InnerException, typeof(UTF.AssertInconclusiveException)); } [TestMethod] public void RunAssemblyInitializeShouldThrowTestFailedExceptionWithNonAssertExceptions() { - DummyTestClass.AssemblyInitializeMethodBody = (tc) => { throw new ArgumentException("Argument exception"); }; + DummyTestClass.AssemblyInitializeMethodBody = tc => { throw new ArgumentException("Some exception message", new InvalidOperationException("Inner exception message")); }; this.testAssemblyInfo.AssemblyInitializeMethod = typeof(DummyTestClass).GetMethod("AssemblyInitializeMethod"); var exception = ActionUtility.PerformActionAndReturnException(() => this.testAssemblyInfo.RunAssemblyInitialize(this.testContext)) as TestFailedException; @@ -209,11 +215,13 @@ public void RunAssemblyInitializeShouldThrowTestFailedExceptionWithNonAssertExce Assert.IsNotNull(exception); Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); Assert.AreEqual( - "Assembly Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestAssemblyInfoTests+DummyTestClass.AssemblyInitializeMethod threw exception. System.ArgumentException: System.ArgumentException: Argument exception. Aborting test execution.", + "Assembly Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestAssemblyInfoTests+DummyTestClass.AssemblyInitializeMethod threw exception. System.ArgumentException: Some exception message. Aborting test execution.", exception.Message); StringAssert.StartsWith( exception.StackTraceInformation.ErrorStackTrace, " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestAssemblyInfoTests.<>c."); + Assert.IsInstanceOfType(exception.InnerException, typeof(ArgumentException)); + Assert.IsInstanceOfType(exception.InnerException.InnerException, typeof(InvalidOperationException)); } [TestMethod] diff --git a/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestClassInfoTests.cs b/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestClassInfoTests.cs index 4e6921e027..0e79e93565 100644 --- a/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestClassInfoTests.cs +++ b/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestClassInfoTests.cs @@ -227,7 +227,7 @@ public void TestClassInfoHasExecutableCleanupMethodShouldReturnTrueIfClassHasCle public void RunClassInitializeShouldNotInvokeIfClassInitializeIsNull() { var classInitCallCount = 0; - DummyTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyTestClass.ClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.ClassInitializeMethod = null; @@ -239,7 +239,7 @@ public void RunClassInitializeShouldNotInvokeIfClassInitializeIsNull() [TestMethod] public void RunClassInitializeShouldThrowIfTestContextIsNull() { - DummyTestClass.ClassInitializeMethodBody = (tc) => { }; + DummyTestClass.ClassInitializeMethodBody = tc => { }; this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); @@ -252,7 +252,7 @@ public void RunClassInitializeShouldThrowIfTestContextIsNull() public void RunClassInitializeShouldNotExecuteClassInitializeIfItHasAlreadyExecuted() { var classInitCallCount = 0; - DummyTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyTestClass.ClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.IsClassInitializeExecuted = true; this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); @@ -266,7 +266,7 @@ public void RunClassInitializeShouldNotExecuteClassInitializeIfItHasAlreadyExecu public void RunClassInitializeShouldExecuteClassInitialize() { var classInitCallCount = 0; - DummyTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyTestClass.ClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); this.testClassInfo.RunClassInitialize(this.testContext); @@ -277,7 +277,7 @@ public void RunClassInitializeShouldExecuteClassInitialize() [TestMethod] public void RunClassInitializeShouldSetClassInitializeExecutedFlag() { - DummyTestClass.ClassInitializeMethodBody = (tc) => { }; + DummyTestClass.ClassInitializeMethodBody = tc => { }; this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); this.testClassInfo.RunClassInitialize(this.testContext); @@ -289,7 +289,7 @@ public void RunClassInitializeShouldSetClassInitializeExecutedFlag() public void RunClassInitializeShouldOnlyRunOnce() { var classInitCallCount = 0; - DummyTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyTestClass.ClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); this.testClassInfo.RunClassInitialize(this.testContext); @@ -302,7 +302,7 @@ public void RunClassInitializeShouldOnlyRunOnce() public void RunClassInitializeShouldRunOnlyOnceIfThereIsNoDerivedClassInitializeAndSetClassInitializeExecutedFlag() { var classInitCallCount = 0; - DummyBaseTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyBaseTestClass.ClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.BaseClassInitAndCleanupMethods.Enqueue( Tuple.Create(typeof(DummyBaseTestClass).GetMethod("InitBaseClassMethod"), (MethodInfo)null)); @@ -316,7 +316,7 @@ public void RunClassInitializeShouldRunOnlyOnceIfThereIsNoDerivedClassInitialize [TestMethod] public void RunClassInitializeShouldSetClassInitializationExceptionOnException() { - DummyTestClass.ClassInitializeMethodBody = (tc) => UTF.Assert.Inconclusive("Test Inconclusive"); + DummyTestClass.ClassInitializeMethodBody = tc => UTF.Assert.Inconclusive("Test Inconclusive"); this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); var exception = ActionUtility.PerformActionAndReturnException(() => this.testClassInfo.RunClassInitialize(this.testContext)); @@ -328,8 +328,8 @@ public void RunClassInitializeShouldSetClassInitializationExceptionOnException() public void RunClassInitializeShouldExecuteBaseClassInitializeMethod() { var classInitCallCount = 0; - DummyBaseTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount++; - DummyDerivedTestClass.DerivedClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyBaseTestClass.ClassInitializeMethodBody = tc => classInitCallCount++; + DummyDerivedTestClass.DerivedClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.BaseClassInitAndCleanupMethods.Enqueue( new Tuple( @@ -347,8 +347,8 @@ public void RunClassInitializeShouldNotExecuteBaseClassInitializeMethodIfClassIn { var classInitCallCount = 0; - DummyBaseTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount += 2; - DummyDerivedTestClass.DerivedClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyBaseTestClass.ClassInitializeMethodBody = tc => classInitCallCount += 2; + DummyDerivedTestClass.DerivedClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.BaseClassInitAndCleanupMethods.Enqueue( new Tuple( @@ -367,7 +367,7 @@ public void RunClassInitializeShouldNotExecuteBaseClassInitializeMethodIfClassIn public void RunClassInitializeShouldExecuteBaseClassInitializeIfDerivedClassInitializeIsNull() { var classInitCallCount = 0; - DummyBaseTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyBaseTestClass.ClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.BaseClassInitAndCleanupMethods.Enqueue( new Tuple( @@ -383,7 +383,7 @@ public void RunClassInitializeShouldExecuteBaseClassInitializeIfDerivedClassInit public void RunClassInitializeShouldNotExecuteBaseClassIfBaseClassInitializeIsNull() { var classInitCallCount = 0; - DummyTestClass.ClassInitializeMethodBody = (tc) => classInitCallCount++; + DummyTestClass.ClassInitializeMethodBody = tc => classInitCallCount++; this.testClassInfo.BaseClassInitAndCleanupMethods.Enqueue(new Tuple(null, null)); this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); @@ -396,7 +396,7 @@ public void RunClassInitializeShouldNotExecuteBaseClassIfBaseClassInitializeIsNu [TestMethod] public void RunClassInitializeShouldThrowTestFailedExceptionOnBaseInitializeMethodWithNonAssertExceptions() { - DummyBaseTestClass.ClassInitializeMethodBody = (tc) => { throw new ArgumentException("Argument exception"); }; + DummyBaseTestClass.ClassInitializeMethodBody = tc => { throw new ArgumentException("Some exception message", new InvalidOperationException("Inner exception message")); }; this.testClassInfo.BaseClassInitAndCleanupMethods.Enqueue(new Tuple( typeof(DummyBaseTestClass).GetMethod("InitBaseClassMethod"), @@ -407,49 +407,57 @@ public void RunClassInitializeShouldThrowTestFailedExceptionOnBaseInitializeMeth Assert.IsNotNull(exception); Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); Assert.AreEqual( - "Class Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests+DummyTestClass.InitBaseClassMethod threw exception. System.ArgumentException: System.ArgumentException: Argument exception.", + "Class Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests+DummyTestClass.InitBaseClassMethod threw exception. System.ArgumentException: Some exception message.", exception.Message); StringAssert.StartsWith( exception.StackTraceInformation.ErrorStackTrace, - " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests.<>c."); + " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests.<>c."); + Assert.IsInstanceOfType(exception.InnerException, typeof(ArgumentException)); + Assert.IsInstanceOfType(exception.InnerException.InnerException, typeof(InvalidOperationException)); } [TestMethod] public void RunClassInitializeShouldThrowTestFailedExceptionOnAssertionFailure() { - DummyTestClass.ClassInitializeMethodBody = (tc) => UTF.Assert.Fail("Test failure"); + DummyTestClass.ClassInitializeMethodBody = tc => UTF.Assert.Fail("Test failure"); this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); var exception = ActionUtility.PerformActionAndReturnException(() => this.testClassInfo.RunClassInitialize(this.testContext)) as TestFailedException; Assert.IsNotNull(exception); Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); - StringAssert.Contains(exception.Message, "Test failure"); + Assert.AreEqual( + "Class Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests+DummyTestClass.ClassInitializeMethod threw exception. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Assert.Fail failed. Test failure.", + exception.Message); StringAssert.StartsWith( exception.StackTraceInformation.ErrorStackTrace, " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests.<>c."); + Assert.IsInstanceOfType(exception.InnerException, typeof(UTF.AssertFailedException)); } [TestMethod] public void RunClassInitializeShouldThrowTestFailedExceptionWithInconclusiveOnAssertInconclusive() { - DummyTestClass.ClassInitializeMethodBody = (tc) => UTF.Assert.Inconclusive("Test Inconclusive"); + DummyTestClass.ClassInitializeMethodBody = tc => UTF.Assert.Inconclusive("Test Inconclusive"); this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); var exception = ActionUtility.PerformActionAndReturnException(() => this.testClassInfo.RunClassInitialize(this.testContext)) as TestFailedException; Assert.IsNotNull(exception); Assert.AreEqual(UnitTestOutcome.Inconclusive, exception.Outcome); - StringAssert.Contains(exception.Message, "Test Inconclusive"); + Assert.AreEqual( + "Class Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests+DummyTestClass.ClassInitializeMethod threw exception. Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException: Assert.Inconclusive failed. Test Inconclusive.", + exception.Message); StringAssert.StartsWith( exception.StackTraceInformation.ErrorStackTrace, " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests.<>c."); + Assert.IsInstanceOfType(exception.InnerException, typeof(UTF.AssertInconclusiveException)); } [TestMethod] public void RunClassInitializeShouldThrowTestFailedExceptionWithNonAssertExceptions() { - DummyTestClass.ClassInitializeMethodBody = (tc) => { throw new ArgumentException("Argument exception"); }; + DummyTestClass.ClassInitializeMethodBody = tc => { throw new ArgumentException("Argument exception"); }; this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); var exception = ActionUtility.PerformActionAndReturnException(() => this.testClassInfo.RunClassInitialize(this.testContext)) as TestFailedException; @@ -457,17 +465,17 @@ public void RunClassInitializeShouldThrowTestFailedExceptionWithNonAssertExcepti Assert.IsNotNull(exception); Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); Assert.AreEqual( - "Class Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests+DummyTestClass.ClassInitializeMethod threw exception. System.ArgumentException: System.ArgumentException: Argument exception.", + "Class Initialization method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests+DummyTestClass.ClassInitializeMethod threw exception. System.ArgumentException: Argument exception.", exception.Message); StringAssert.StartsWith( exception.StackTraceInformation.ErrorStackTrace, - " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests.<>c."); + " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests.<>c."); } [TestMethod] public void RunClassInitializeShouldThrowForAlreadyExecutedTestClassInitWithException() { - DummyTestClass.ClassInitializeMethodBody = (tc) => { }; + DummyTestClass.ClassInitializeMethodBody = tc => { }; this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); this.testClassInfo.ClassInitializationException = new TestFailedException(UnitTestOutcome.Failed, "Cached Test failure"); @@ -483,7 +491,7 @@ public void RunClassInitializeShouldThrowForAlreadyExecutedTestClassInitWithExce [TestMethod] public void RunAssemblyInitializeShouldPassOnTheTestContextToAssemblyInitMethod() { - DummyTestClass.ClassInitializeMethodBody = (tc) => { Assert.AreEqual(tc, this.testContext); }; + DummyTestClass.ClassInitializeMethodBody = tc => { Assert.AreEqual(tc, this.testContext); }; this.testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); this.testClassInfo.RunClassInitialize(this.testContext); diff --git a/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestMethodInfoTests.cs b/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestMethodInfoTests.cs index 9038b6c2d8..c0b160e6cd 100644 --- a/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestMethodInfoTests.cs +++ b/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Execution/TestMethodInfoTests.cs @@ -10,10 +10,8 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution using System; using System.Collections.Generic; using System.Globalization; - using System.IO; using System.Linq; using System.Reflection; - using System.Text; using System.Threading; using System.Threading.Tasks; @@ -168,7 +166,7 @@ public void TestMethodInfoInvokeAsyncShouldHandleAssertInconclusive() [TestMethodV1] public void TestMethodInfoInvokeShouldHandleThrowAssertInconclusive() { - DummyTestClass.TestMethodBody = (d) => { throw new UTF.AssertInconclusiveException(); }; + DummyTestClass.TestMethodBody = d => { throw new UTF.AssertInconclusiveException(); }; var dummyMethodInfo = typeof(DummyTestClass).GetMethod("DummyTestMethod"); var method = new TestMethodInfo( @@ -184,7 +182,7 @@ public void TestMethodInfoInvokeShouldHandleThrowAssertInconclusive() [TestMethodV1] public void TestMethodInfoInvokeShouldHandleAssertInconclusive() { - DummyTestClass.TestMethodBody = (d) => { UTF.Assert.Inconclusive(); }; + DummyTestClass.TestMethodBody = d => { UTF.Assert.Inconclusive(); }; var dummyMethodInfo = typeof(DummyTestClass).GetMethod("DummyTestMethod"); var method = new TestMethodInfo( @@ -488,91 +486,100 @@ public void TestMethodInfoInvokeShouldNotThrowIfTestInitializeForBaseClassIsNull } [TestMethodV1] - public void TestMethodInfoInvokeShouldMarkOutcomeAsFailIfTestInitializeThrows() + public void TestMethodInfoInvokeWhenTestThrowsReturnsExpectedResult() { - DummyTestClass.TestInitializeMethodBody = classInstance => { throw new NotImplementedException(); }; - this.testClassInfo.TestInitializeMethod = typeof(DummyTestClass).GetMethod("DummyTestInitializeMethod"); - - var result = this.testMethodInfo.Invoke(null); - - Assert.AreEqual(UTF.UnitTestOutcome.Failed, result.Outcome); - } - - [TestMethodV1] - public void TestMethodInfoInvokeShouldSetErrorMessageIfTestInitializeThrows() - { - DummyTestClass.TestInitializeMethodBody = classInstance => { throw new NotImplementedException("dummyErrorMessage"); }; + // Arrange. + DummyTestClass.TestInitializeMethodBody = classInstance => { throw new ArgumentException("Some exception message", new InvalidOperationException("Inner exception message")); }; this.testClassInfo.TestInitializeMethod = typeof(DummyTestClass).GetMethod("DummyTestInitializeMethod"); var errorMessage = string.Format( Resource.UTA_InitMethodThrows, typeof(DummyTestClass).FullName, this.testClassInfo.TestInitializeMethod.Name, - "System.NotImplementedException: dummyErrorMessage"); - - var exception = this.testMethodInfo.Invoke(null).TestFailureException as TestFailedException; + "System.ArgumentException: Some exception message ---> System.InvalidOperationException: Inner exception message"); - Assert.IsNotNull(exception); - Assert.AreEqual(errorMessage, exception?.Message); - } + this.testMethodOptions.ExpectedException = this.expectedException; + var testMethodInfo = new TestMethodInfo(this.methodInfo, this.testClassInfo, this.testMethodOptions); - [TestMethodV1] - public void TestMethodInfoInvokeShouldSetStackTraceInformationIfTestInitializeThrows() - { - DummyTestClass.TestInitializeMethodBody = classInstance => { throw new NotImplementedException("dummyErrorMessage"); }; - this.testClassInfo.TestInitializeMethod = typeof(DummyTestClass).GetMethod("DummyTestInitializeMethod"); + // Act. + var result = testMethodInfo.Invoke(null); - var exception = this.testMethodInfo.Invoke(null).TestFailureException as TestFailedException; + // Assert. + Assert.AreEqual(UTF.UnitTestOutcome.Failed, result.Outcome); + var exception = result.TestFailureException as TestFailedException; Assert.IsNotNull(exception); + Assert.AreEqual(errorMessage, exception.Message); + Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); + Assert.IsInstanceOfType(exception.InnerException, typeof(ArgumentException)); + Assert.IsInstanceOfType(exception.InnerException.InnerException, typeof(InvalidOperationException)); + StringAssert.StartsWith( - exception?.StackTraceInformation.ErrorStackTrace, - " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); + exception.StackTraceInformation.ErrorStackTrace, + " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); } [TestMethodV1] - public void TestMethodInfoInvokeShouldSetErrorMessageIfTestInitializeThrowsUnitTestAssertException() + public void TestMethodInfoInvokeWhenTestThrowsAssertFailReturnsExpectedResult() { + // Arrange. DummyTestClass.TestInitializeMethodBody = classInstance => { UTF.Assert.Fail("dummyFailMessage"); }; this.testClassInfo.TestInitializeMethod = typeof(DummyTestClass).GetMethod("DummyTestInitializeMethod"); - const string ErrorMessage = "Assert.Fail failed. dummyFailMessage"; - - var exception = this.testMethodInfo.Invoke(null).TestFailureException as TestFailedException; + var errorMessage = string.Format( + Resource.UTA_InitMethodThrows, + typeof(DummyTestClass).FullName, + this.testClassInfo.TestInitializeMethod.Name, + "Assert.Fail failed. dummyFailMessage"); - Assert.IsNotNull(exception); - Assert.AreEqual(ErrorMessage, exception?.Message); - } + this.testMethodOptions.ExpectedException = this.expectedException; + var testMethodInfo = new TestMethodInfo(this.methodInfo, this.testClassInfo, this.testMethodOptions); - [TestMethodV1] - public void TestMethodInfoInvokeShouldSetStackTraceInformationIfTestInitializeThrowsUnitTestAssertException() - { - DummyTestClass.TestInitializeMethodBody = classInstance => { UTF.Assert.Fail("dummyFailMessage"); }; - this.testClassInfo.TestInitializeMethod = typeof(DummyTestClass).GetMethod("DummyTestInitializeMethod"); + // Act. + var result = testMethodInfo.Invoke(null); - var exception = this.testMethodInfo.Invoke(null).TestFailureException as TestFailedException; + // Assert. + Assert.AreEqual(UTF.UnitTestOutcome.Failed, result.Outcome); + var exception = result.TestFailureException as TestFailedException; Assert.IsNotNull(exception); + Assert.AreEqual(errorMessage, exception.Message); + Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); + Assert.IsInstanceOfType(exception.InnerException, typeof(UTF.AssertFailedException)); + StringAssert.StartsWith( - exception?.StackTraceInformation.ErrorStackTrace, - " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); + exception.StackTraceInformation.ErrorStackTrace, + " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); } [TestMethodV1] - public void TestMethodInfoInvokeShouldSetTestInitializeExceptionEvenIfMethodHasExpectedExceptionAttriute() + public void TestMethodInfoInvokeWhenTestThrowsAssertInconclusiveReturnsExpectedResult() { // Arrange. - DummyTestClass.TestInitializeMethodBody = classInstance => { UTF.Assert.Fail("dummyFailMessage"); }; + DummyTestClass.TestInitializeMethodBody = classInstance => { UTF.Assert.Inconclusive("dummyFailMessage"); }; this.testClassInfo.TestInitializeMethod = typeof(DummyTestClass).GetMethod("DummyTestInitializeMethod"); - const string ErrorMessage = "Assert.Fail failed. dummyFailMessage"; + var errorMessage = string.Format( + Resource.UTA_InitMethodThrows, + typeof(DummyTestClass).FullName, + this.testClassInfo.TestInitializeMethod.Name, + "Assert.Inconclusive failed. dummyFailMessage"); this.testMethodOptions.ExpectedException = this.expectedException; var testMethodInfo = new TestMethodInfo(this.methodInfo, this.testClassInfo, this.testMethodOptions); // Act. - var exception = testMethodInfo.Invoke(null).TestFailureException as TestFailedException; + var result = testMethodInfo.Invoke(null); // Assert. + Assert.AreEqual(UTF.UnitTestOutcome.Inconclusive, result.Outcome); + + var exception = result.TestFailureException as TestFailedException; Assert.IsNotNull(exception); - Assert.AreEqual(ErrorMessage, exception?.Message); + Assert.AreEqual(errorMessage, exception.Message); + Assert.AreEqual(UnitTestOutcome.Inconclusive, exception.Outcome); + Assert.IsInstanceOfType(exception.InnerException, typeof(UTF.AssertInconclusiveException)); + + StringAssert.StartsWith( + exception.StackTraceInformation.ErrorStackTrace, + " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); } #endregion @@ -675,47 +682,91 @@ public void TestMethodInfoInvokeShouldCallTestCleanupForBaseTestClassesAlways() } [TestMethodV1] - public void TestMethodInfoInvokeShouldMarkOutcomeAsFailedIfTestCleanupThrows() + public void TestMethodInfoInvokeWhenTestCleanupThrowsReturnsExpectedResult() { - DummyTestClass.TestCleanupMethodBody = classInstance => { throw new NotImplementedException(); }; + DummyTestClass.TestCleanupMethodBody = classInstance => { throw new ArgumentException("Some exception message", new InvalidOperationException("Inner exception message")); }; this.testClassInfo.TestCleanupMethod = typeof(DummyTestClass).GetMethod("DummyTestCleanupMethod"); + var expectedErrorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_CleanupMethodThrows, + typeof(DummyTestClass).FullName, + this.testClassInfo.TestCleanupMethod.Name, + typeof(ArgumentException).ToString(), + "Some exception message"); + var result = this.testMethodInfo.Invoke(null); Assert.AreEqual(UTF.UnitTestOutcome.Failed, result.Outcome); + + var exception = result.TestFailureException as TestFailedException; + Assert.IsNotNull(exception); + Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); + Assert.AreEqual(expectedErrorMessage, exception.Message); + Assert.IsInstanceOfType(exception.InnerException, typeof(ArgumentException)); + Assert.IsInstanceOfType(exception.InnerException.InnerException, typeof(InvalidOperationException)); + + StringAssert.StartsWith( + exception.StackTraceInformation.ErrorStackTrace, + " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); } [TestMethodV1] - public void TestMethodInfoInvokeShouldSetErrorMessageIfTestCleanupThrows() + public void TestMethodInfoInvokeWhenTestCleanupThrowsAssertInconclusiveReturnsExpectedResult() { - DummyTestClass.TestCleanupMethodBody = classInstance => { throw new NotImplementedException("dummyErrorMessage"); }; + DummyTestClass.TestCleanupMethodBody = classInstance => { UTF.Assert.Inconclusive("Test inconclusive"); }; this.testClassInfo.TestCleanupMethod = typeof(DummyTestClass).GetMethod("DummyTestCleanupMethod"); - var exception = this.testMethodInfo.Invoke(null).TestFailureException as TestFailedException; - var errorMessage = string.Format( + var expectedErrorMessage = string.Format( CultureInfo.CurrentCulture, Resource.UTA_CleanupMethodThrows, typeof(DummyTestClass).FullName, this.testClassInfo.TestCleanupMethod.Name, - typeof(NotImplementedException).ToString(), - "System.NotImplementedException: dummyErrorMessage"); + typeof(UTF.AssertInconclusiveException).ToString(), + "Assert.Inconclusive failed. Test inconclusive"); + + var result = this.testMethodInfo.Invoke(null); + + Assert.AreEqual(UTF.UnitTestOutcome.Inconclusive, result.Outcome); + var exception = result.TestFailureException as TestFailedException; Assert.IsNotNull(exception); - Assert.AreEqual(errorMessage, exception?.Message); + Assert.AreEqual(UnitTestOutcome.Inconclusive, exception.Outcome); + Assert.AreEqual(expectedErrorMessage, exception.Message); + Assert.IsInstanceOfType(exception.InnerException, typeof(UTF.AssertInconclusiveException)); + + StringAssert.StartsWith( + exception.StackTraceInformation.ErrorStackTrace, + " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); } [TestMethodV1] - public void TestMethodInfoInvokeShouldSetStackTraceInformationIfTestCleanupThrows() + public void TestMethodInfoInvokeWhenTestCleanupThrowsAssertFailedReturnsExpectedResult() { - DummyTestClass.TestCleanupMethodBody = classInstance => { throw new NotImplementedException(); }; + DummyTestClass.TestCleanupMethodBody = classInstance => { UTF.Assert.Fail("Test failed"); }; this.testClassInfo.TestCleanupMethod = typeof(DummyTestClass).GetMethod("DummyTestCleanupMethod"); - var exception = this.testMethodInfo.Invoke(null).TestFailureException as TestFailedException; + var expectedErrorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_CleanupMethodThrows, + typeof(DummyTestClass).FullName, + this.testClassInfo.TestCleanupMethod.Name, + typeof(UTF.AssertFailedException).ToString(), + "Assert.Fail failed. Test failed"); + + var result = this.testMethodInfo.Invoke(null); + + Assert.AreEqual(UTF.UnitTestOutcome.Failed, result.Outcome); + var exception = result.TestFailureException as TestFailedException; Assert.IsNotNull(exception); + Assert.AreEqual(UnitTestOutcome.Failed, exception.Outcome); + Assert.AreEqual(expectedErrorMessage, exception.Message); + Assert.IsInstanceOfType(exception.InnerException, typeof(UTF.AssertFailedException)); + StringAssert.StartsWith( - exception?.StackTraceInformation.ErrorStackTrace, - " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); + exception.StackTraceInformation.ErrorStackTrace, + " at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests.<>c.b__"); } [TestMethodV1] @@ -739,7 +790,7 @@ public void TestMethodInfoInvokeShouldAppendErrorMessagesIfBothTestMethodAndTest typeof(DummyTestClass).FullName, this.testClassInfo.TestCleanupMethod.Name, typeof(NotImplementedException).ToString(), - "System.NotImplementedException: dummyErrorMessage"); + "dummyErrorMessage"); Assert.AreEqual(result.Outcome, UTF.UnitTestOutcome.Failed); Assert.IsNotNull(exception); diff --git a/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Extensions/ExceptionExtensionsTests.cs b/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Extensions/ExceptionExtensionsTests.cs index 455dac7d16..000069c0ba 100644 --- a/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Extensions/ExceptionExtensionsTests.cs +++ b/test/UnitTests/MSTest.CoreAdapter.Unit.Tests/Extensions/ExceptionExtensionsTests.cs @@ -214,23 +214,5 @@ public void IsUnitTestAssertExceptionSetsOutcomeAsFailedIfAssertFailedException( Assert.AreEqual("Dummy Message", exceptionMessage); } #endregion - - #region TryGetTestFailureExceptionMessageAndStackTrace scenarios - - [TestMethod] - public void TryGetTestFailureExceptionMessageAndStackTraceFillsInMessageAndStackTrace() - { - StringBuilder message = new StringBuilder(); - StringBuilder stackTrace = new StringBuilder(); - var testFailureException = new TestFailedException(UnitTestOutcome.NotFound, "DummyMessage", new StackTraceInformation("DummyStack")); - - testFailureException.TryGetTestFailureExceptionMessageAndStackTrace(message, stackTrace); - - StringAssert.StartsWith(message.ToString(), "DummyMessage"); - StringAssert.StartsWith(stackTrace.ToString(), "DummyStack"); - } - - #endregion - } }