private void RunTestMethod(object testObj, TestMethod testMethod) { if (testMethod == null) return; StringBuilder output = new StringBuilder(); StringWriter outputWriter = new StringWriter(output); ProcessCycleStopwatch methodCycleStopwatch = null; Stopwatch methodStopwatch = new Stopwatch(); testMethod.Outcome = UnitTestOutcome.Running; TestContext.ResetOutput(); TestContext.ActiveTestMethod = testMethod; WriteMessage(TestingResources.TestMethodRunning(testMethod.Name)); try { if (ProcessCycleStopwatch.IsSupported) methodCycleStopwatch = ProcessCycleStopwatch.StartNew(); methodStopwatch.Start(); ParameterInfo[] paramInfo = testMethod.MethodInfo.GetParameters(); if (AttachDebugger) { // Only attach to the first test that runs AttachDebugger = false; // Indicate to the user to attach the debugger, or Windows will // put up the annoying problem reporting dialog. WriteMessage("[Attach debugger now or press a key to continue]"); while (true) { if (Debugger.IsAttached) { WriteMessage("Debugger is attached"); Debugger.Break(); break; } else if (!Console.KeyAvailable) { Thread.Sleep(250); continue; } else { Console.ReadKey(true); break; } } } if (testMethod.MethodInfo.IsStatic) { if (paramInfo.Length == 0) testMethod.MethodInfo.Invoke(null, null); else if (paramInfo.Length == 1 && paramInfo[0].ParameterType == typeof(TestContext)) testMethod.MethodInfo.Invoke(null, new object[] { ToastTool.TestContext }); else Debug.Fail("Unsupported test method type"); } else { if (paramInfo.Length == 0) testMethod.MethodInfo.Invoke(testObj, null); else Debug.Fail("Unsupported test method type"); } } catch (Exception e) { // Because we are using reflection the test exception will be inside a reflection invocation exception if (e.InnerException != null) e = e.InnerException; // Check if one of the expected exceptions if (testMethod.ExpectedExceptions.Length > 0) { if (Array.IndexOf<Type>(testMethod.ExpectedExceptions, e.GetType()) != -1) // Exception was expected, ignore it e = null; } if (e != null) { testMethod.Exception = e; testMethod.Outcome = UnitTestOutcome.Failed; } } finally { outputWriter.Close(); methodStopwatch.Stop(); testMethod.ExecutionTime = new TimeSpan(methodStopwatch.ElapsedTicks); if (methodCycleStopwatch != null) { methodCycleStopwatch.Stop(); testMethod.ExecutionCycles = unchecked((long)methodCycleStopwatch.ElapsedCycles); } } if (testMethod.Outcome == UnitTestOutcome.Running) testMethod.Outcome = UnitTestOutcome.Passed; testMethod.Output = TestContext.GetOutput(); TestContext.ActiveTestMethod = null; WriteMessage(TestingResources.PassFailMessage( (testMethod.Exception != null) ? TestingResources.FailedAllCaps : TestingResources.PassedAllCaps, testMethod.Name)); if (testMethod.Exception != null) { WriteError(testMethod.Exception.ToString()); } }
private void WriteTestMethod(TsonTextWriter wr, string canonicalMethodName, TestMethod testMethod) { if (testMethod == null) return; wr.WriteObjectPropertyStart(canonicalMethodName); wr.WriteProperty("Name", testMethod.Name); wr.WriteProperty("Outcome", testMethod.Outcome.ToString()); wr.WriteProperty("ExecutionTime", testMethod.ExecutionTime.ToString()); if (testMethod.ExecutionCycles != 0) wr.WriteProperty("TotalCycles", testMethod.ExecutionCycles.ToString()); ExplicitTestMethod explicitTestMethod = testMethod as ExplicitTestMethod; if (explicitTestMethod != null) wr.WriteProperty("Order", explicitTestMethod.Order.ToString()); if (!String.IsNullOrEmpty(testMethod.Output)) { wr.WriteProperty("Output", testMethod.Output); } if (testMethod.Exception != null) { wr.WriteObjectPropertyStart("Failure"); wr.WriteProperty("Message", testMethod.Exception.Message); wr.WriteArrayPropertyStart("Stack"); string stackTrace = testMethod.Exception.StackTrace; if (stackTrace != null) { Match m = stackRegex.Match(stackTrace); while (m.Success) { wr.WriteArrayObjectStart(); wr.WriteProperty("FileName", m.Groups[2].Value); wr.WriteProperty("MethodName", m.Groups[1].Value); wr.WriteProperty("Line", m.Groups[3].Value); wr.WriteArrayObjectEnd(); m = m.NextMatch(); } } wr.WriteArrayPropertyEnd(); // Stack wr.WriteObjectPropertyEnd(); // Failure } wr.WriteObjectPropertyEnd(); // TestMethod }
// This constructor is used so that each test initialize/cleanup invocation can have a separate outcome internal TestMethod(TestMethod other) { this.MethodInfo = other.MethodInfo; this.Outcome = other.Outcome; this.ExpectedExceptions = other.ExpectedExceptions; }