in src/Adapter/MSTest.CoreAdapter/Execution/TestClassInfo.cs [243:340]
public void RunClassInitialize(TestContext testContext)
{
// If no class initialize and no base class initialize, return
if (this.ClassInitializeMethod is null && !this.BaseClassInitAndCleanupMethods.Any(p => p.Item1 != null))
{
return;
}
if (testContext == null)
{
throw new NullReferenceException(Resource.TestContextIsNull);
}
MethodInfo initializeMethod = null;
string failedClassInitializeMethodName = string.Empty;
// If class initialization is not done, then do it.
if (!this.IsClassInitializeExecuted)
{
// Aquiring a lock is usually a costly operation which does not need to be
// performed every time if the class init is already executed.
lock (this.testClassExecuteSyncObject)
{
// Perform a check again.
if (!this.IsClassInitializeExecuted)
{
try
{
// ClassInitialize methods for base classes are called in reverse order of discovery
// Base -> Child TestClass
var baseClassInitializeStack = new Stack<Tuple<MethodInfo, MethodInfo>>(
this.BaseClassInitAndCleanupMethods.Where(p => p.Item1 != null));
while (baseClassInitializeStack.Count > 0)
{
var baseInitCleanupMethods = baseClassInitializeStack.Pop();
initializeMethod = baseInitCleanupMethods.Item1;
initializeMethod?.InvokeAsSynchronousTask(null, testContext);
if (baseInitCleanupMethods.Item2 != null)
{
this.BaseClassCleanupMethodsStack.Push(baseInitCleanupMethods.Item2);
}
}
initializeMethod = null;
if (this.classInitializeMethod != null)
{
this.ClassInitializeMethod.InvokeAsSynchronousTask(null, testContext);
}
}
catch (Exception ex)
{
this.ClassInitializationException = ex;
failedClassInitializeMethodName = initializeMethod?.Name ?? this.ClassInitializeMethod.Name;
}
finally
{
this.IsClassInitializeExecuted = true;
}
}
}
}
// If classInitialization was successful, then don't do anything
if (this.ClassInitializationException == null)
{
return;
}
if (this.ClassInitializationException is TestFailedException)
{
throw this.ClassInitializationException;
}
// 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 testFailedException = new TestFailedException(outcome, errorMessage, exceptionStackTraceInfo);
this.ClassInitializationException = testFailedException;
throw testFailedException;
}