public ClassCleanupManager( IEnumerable <UnitTestElement> testsToRun, ClassCleanupBehavior?lifecycleFromMsTest, ClassCleanupBehavior lifecycleFromAssembly, ReflectHelper reflectHelper = null) { this.remainingTestsByClass = testsToRun.GroupBy(t => t.TestMethod.FullClassName) .ToDictionary( g => g.Key, g => new HashSet <string>(g.Select(t => t.DisplayName))); this.lifecycleFromMsTest = lifecycleFromMsTest; this.lifecycleFromAssembly = lifecycleFromAssembly; this.reflectHelper = reflectHelper ?? new ReflectHelper(); }
/// <summary> /// Run class cleanup methods /// </summary> /// <param name="classCleanupLifecycle">The current lifecyle position that ClassCleanup is executing from</param> /// <returns> /// Any exception that can be thrown as part of a class cleanup as warning messages. /// </returns> public string RunClassCleanup(ClassCleanupBehavior classCleanupLifecycle = ClassCleanupBehavior.EndOfAssembly) { if (this.ClassCleanupMethod is null && this.BaseClassInitAndCleanupMethods.All(p => p.Item2 == null)) { return(null); } if (!this.IsClassCleanupExecuted) { lock (this.testClassExecuteSyncObject) { if (this.IsClassCleanupExecuted) { return(null); } if (this.IsClassInitializeExecuted || this.ClassInitializeMethod is null) { MethodInfo classCleanupMethod = null; try { classCleanupMethod = this.ClassCleanupMethod; classCleanupMethod?.InvokeAsSynchronousTask(null); var baseClassCleanupQueue = new Queue <MethodInfo>(this.BaseClassCleanupMethodsStack); while (baseClassCleanupQueue.Count > 0) { classCleanupMethod = baseClassCleanupQueue.Dequeue(); classCleanupMethod?.InvokeAsSynchronousTask(null); } this.IsClassCleanupExecuted = true; return(null); } catch (Exception exception) { var realException = exception.InnerException ?? exception; this.ClassCleanupException = realException; string errorMessage; // special case AssertFailedException to trim off part of the stack trace if (realException is AssertFailedException || realException is AssertInconclusiveException) { errorMessage = realException.Message; } else { errorMessage = StackTraceHelper.GetExceptionMessage(realException); } var exceptionStackTraceInfo = realException.TryGetStackTraceInformation(); errorMessage = string.Format( CultureInfo.CurrentCulture, Resource.UTA_ClassCleanupMethodWasUnsuccesful, classCleanupMethod.DeclaringType.Name, classCleanupMethod.Name, errorMessage, exceptionStackTraceInfo?.ErrorStackTrace); if (classCleanupLifecycle == ClassCleanupBehavior.EndOfClass) { var testFailedException = new TestFailedException(UnitTestOutcome.Failed, errorMessage, exceptionStackTraceInfo); this.ClassCleanupException = testFailedException; throw testFailedException; } return(errorMessage); } } } } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="ClassCleanupAttribute"/> class. /// </summary> /// <param name="inheritanceBehavior"> /// Specifies the ClassCleanup Inheritance Behavior /// </param> /// <param name="cleanupBehavior"> /// Specifies the class clean-up behavior. /// To capture output of class clean-up method in logs /// <paramref name="cleanupBehavior"/> must be set to <see cref="ClassCleanupBehavior.EndOfClass"/>. /// </param> public ClassCleanupAttribute(InheritanceBehavior inheritanceBehavior, ClassCleanupBehavior cleanupBehavior) : this(inheritanceBehavior, new ClassCleanupBehavior?(cleanupBehavior)) { }
/// <summary> /// Initializes a new instance of the <see cref="ClassCleanupExecutionAttribute"/> class. /// </summary> /// <param name="cleanupBehavior"> /// Specifies the class clean-up behavior. /// To capture output of class clean-up method in logs /// <paramref name="cleanupBehavior"/> must be set to <see cref="ClassCleanupBehavior.EndOfClass"/>. /// </param> public ClassCleanupExecutionAttribute(ClassCleanupBehavior cleanupBehavior) { this.CleanupBehavior = cleanupBehavior; }
/// <summary> /// Initializes a new instance of the <see cref="ClassCleanupAttribute"/> class. /// </summary> /// <param name="cleanupBehavior"> /// Specifies the class clean-up behavior. /// To capture output of class clean-up method in logs /// <paramref name="cleanupBehavior"/> must be set to <see cref="ClassCleanupBehavior.EndOfClass"/>. /// </param> public ClassCleanupAttribute(ClassCleanupBehavior cleanupBehavior) : this(InheritanceBehavior.None, cleanupBehavior) { }