Skip to content

Instantly share code, notes, and snippets.

@VasylBakalets
Created October 5, 2015 13:18
Show Gist options
  • Save VasylBakalets/61d608e20fa3a97336b9 to your computer and use it in GitHub Desktop.
Save VasylBakalets/61d608e20fa3a97336b9 to your computer and use it in GitHub Desktop.
internal class ReportingHelper
{
// Managed Id of thread which was report setup called in.
private static int _initialThreadId;
/// <summary>
/// Searches for Type by its name in all currentrly loaded assemblies.
/// Used to obtain proper tracker and test suite name for reporting.
/// </summary>
/// <param name="typeName">Fully qualified type name</param>
/// <returns>Type or null if not found</returns>
public static Type GetType(string typeName)
{
var type = Type.GetType(typeName);
if (type != null)
{
return type;
}
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
type = assembly.GetType(typeName);
if (type != null)
{
return type;
}
}
return null;
}
/// <summary>
/// Sets up and starts per-testclass report.
/// Should be called from ClassInitialize method.
/// </summary>
/// <param name="testContext">TestContext instance</param>
public static void SetupReport(TestContext testContext)
{
Report.End();
ActivityStack.Clear();
_initialThreadId = Thread.CurrentThread.ManagedThreadId;
Type testClassType = GetType(testContext.FullyQualifiedTestClassName);
var reportFile = string.Format(
@"{0}\{1}.html",
testContext.ResultsDirectory,
testClassType != null ? testClassType.Name : "TestClassName");
TestReport.Setup(ReportLevel.Info, reportFile, true);
TestReport.ReportEnvironment.UseScreenshotFolder = true;
TestReport.BeginTestSuite(testClassType != null ? testClassType.Name : "TestClassName");
TestReport.BeginTestCase(testContext.TestName);
}
public static void ApplyMultithreadedReportActivityFix()
{
// Small 'dirty' hack designed to workaround default
// Ranorex reporting behavior is not fully compatible with MSTest execution mechanism.
// MSTest launches each test method in new thread,
// and Ranorex ActivityStack singletone logic keeps separate activity stack per thread.
// Therefore reports for entire test class got corrupted (broken hierarchy).
// This hack is designed to workaround the issue by forcing to have the same activity stack for every test method thread.
var stackMapField = typeof (ActivityStack).GetField("stackMap", BindingFlags.Static | BindingFlags.NonPublic);
if (stackMapField == null)
{
return;
}
var stackMap = stackMapField.GetValue(null) as Dictionary<int, ActivityStack>;
if (stackMap == null || stackMap.Count == 0)
{
return;
}
var currentThreadId = Thread.CurrentThread.ManagedThreadId;
if (currentThreadId != _initialThreadId)
{
if (stackMap.ContainsKey(currentThreadId))
{
stackMap.Remove(currentThreadId);
}
stackMap.Add(currentThreadId, stackMap[_initialThreadId]);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment