Exemplo n.º 1
0
        /// <summary>
        /// Runs a single test.
        /// </summary>
        /// <param name="testMethod"> The test Method. </param>
        /// <param name="testContextProperties"> The test context properties. </param>
        /// <returns> The <see cref="UnitTestResult"/>. </returns>
        internal UnitTestResult[] RunSingleTest(TestMethod testMethod, IDictionary <string, object> testContextProperties)
        {
            if (testMethod == null)
            {
                throw new ArgumentNullException(nameof(testMethod));
            }

            try
            {
                using (var writer = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "context"))
                {
                    var properties  = new Dictionary <string, object>(testContextProperties);
                    var testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties);
                    testContext.SetOutcome(TestTools.UnitTesting.UnitTestOutcome.InProgress);

                    // Get the testMethod
                    var testMethodInfo = this.typeCache.GetTestMethodInfo(
                        testMethod,
                        testContext,
                        MSTestSettings.CurrentSettings.CaptureDebugTraces);

                    if (this.classCleanupManager == null && testMethodInfo != null && testMethodInfo.Parent.HasExecutableCleanupMethod)
                    {
                        PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning(Resource.OlderTFMVersionFoundClassCleanup);
                    }

                    if (!this.IsTestMethodRunnable(testMethod, testMethodInfo, out var notRunnableResult))
                    {
                        bool shouldRunClassCleanup = false;
                        this.classCleanupManager?.MarkTestComplete(testMethodInfo, testMethod, out shouldRunClassCleanup);
                        if (shouldRunClassCleanup)
                        {
                            testMethodInfo.Parent.RunClassCleanup(ClassCleanupBehavior.EndOfClass);
                        }

                        return(notRunnableResult);
                    }

                    var result = new TestMethodRunner(testMethodInfo, testMethod, testContext, MSTestSettings.CurrentSettings.CaptureDebugTraces, this.reflectHelper).Execute();
                    this.RunClassCleanupIfEndOfClass(testMethodInfo, testMethod, result);
                    return(result);
                }
            }
            catch (TypeInspectionException ex)
            {
                // Catch any exception thrown while inspecting the test method and return failure.
                return(new UnitTestResult[] { new UnitTestResult(ObjectModel.UnitTestOutcome.Failed, ex.Message) });
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Runs a single test.
        /// </summary>
        /// <param name="testMethod"> The test Method. </param>
        /// <param name="testExecutionRecorder">A instance of TestExecutionRecorderWrapper used to log test execution.</param>
        /// <param name="testContextProperties"> The test context properties. </param>
        /// <returns> The <see cref="UnitTestResult"/>. </returns>
        internal UnitTestResult[] RunSingleTest(TestMethod testMethod, TestExecutionRecorderWrapper testExecutionRecorder, IDictionary <string, object> testContextProperties)
        {
            if (testMethod == null)
            {
                throw new ArgumentNullException("testMethod");
            }

            if (testExecutionRecorder == null)
            {
                throw new ArgumentNullException(nameof(testExecutionRecorder));
            }

            try
            {
                using (var writer = new ThreadSafeStringWriter(CultureInfo.InvariantCulture))
                {
                    var properties  = new Dictionary <string, object>(testContextProperties);
                    var testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties);
                    testContext.SetOutcome(TestTools.UnitTesting.UnitTestOutcome.InProgress);

                    // Get the testMethod
                    var testMethodInfo = this.typeCache.GetTestMethodInfo(testMethod, testContext, testExecutionRecorder, MSTestSettings.CurrentSettings.CaptureDebugTraces);

                    // If the specified TestMethod could not be found, return a NotFound result.
                    if (testMethodInfo == null)
                    {
                        return(new UnitTestResult[] { new UnitTestResult(UnitTestOutcome.NotFound, string.Format(CultureInfo.CurrentCulture, Resource.TestNotFound, testMethod.Name)) });
                    }

                    // If test cannot be executed, then bail out.
                    if (!testMethodInfo.IsRunnable)
                    {
                        return(new UnitTestResult[] { new UnitTestResult(UnitTestOutcome.NotRunnable, testMethodInfo.NotRunnableReason) });
                    }

                    return(new TestMethodRunner(testMethodInfo, testMethod, testContext, MSTestSettings.CurrentSettings.CaptureDebugTraces).Execute());
                }
            }
            catch (TypeInspectionException ex)
            {
                // Catch any exception thrown while inspecting the test method and return failure.
                return(new UnitTestResult[] { new UnitTestResult(UnitTestOutcome.Failed, ex.Message) });
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LogMessageListener"/> class.
        /// </summary>
        /// <param name="captureDebugTraces">Captures debug traces if true.</param>
        public LogMessageListener(bool captureDebugTraces)
        {
            this.captureDebugTraces = captureDebugTraces;

            // Cache the original output/error streams and replace it with the own stream.
            this.redirectedStandardOutput = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "out");
            this.redirectedStandardError  = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "err");

            Logger.OnLogMessage += this.redirectedStandardOutput.WriteLine;

            if (this.captureDebugTraces)
            {
                // This is awkward, it has a side-effect of setting up Console output redirection, but the naming is suggesting that we are
                // just getting TraceListener manager.
                this.traceListenerManager = PlatformServiceProvider.Instance.GetTraceListenerManager(this.redirectedStandardOutput, this.redirectedStandardError);

                // The Debug listener uses Debug.WriteLine and Debug.Write to write the messages, which end up written into Trace.Listeners.
                // These listeners are static and hence shared across the whole process. We need to capture Debug output only for the current
                // test, which was historically done by registering a listener in constructor of this class, and by removing the listener on Dispose.
                // The newly created listener replaced previously registered listener, which was remembered, and put back on dispose.
                //
                // This works well as long as there are no tests running in parallel. But as soon as there are tests running in parallel. Then all the
                // debug output of all tests will be output into the test that was most recently created (because it registered the listener most recently).
                //
                // To prevent mixing of outputs, the ThreadSafeStringWriter was re-implemented for net46 and newer to leverage AsyncLocal, which allows the writer to
                // write only to the output of the current test. This leaves the LogMessageListener with only one task. Make sure that a trace listener is registered
                // as long as there is any active test. This is still done by constructor and Dispose, but instead of replacing the listener every time, we use listenerCount
                // to only add the listerner when there is none, and remove it when we are the last one to dispose.
                //
                // This would break the behavior for net451, but that functionality was moved further into ThreadSafeStringWriter.
                lock (traceLock)
                {
                    if (listenerCount == 0)
                    {
                        redirectedDebugTrace = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "trace");
                        traceListener        = PlatformServiceProvider.Instance.GetTraceListener(redirectedDebugTrace);
                        this.traceListenerManager.Add(traceListener);
                    }

                    listenerCount++;
                }
            }
        }