This is a status service I wrote as I need to update some external testing systems with each test case's status. Sounds like it may work well for your situation of needing to check if a test case failed so you can send an email. However, I would agree with Stub sending the compressed test log at the end is probably more useful.
(I edited out some non-essential information and removed a few methods that wouldn't apply outside our specific system.)
/// <summary>
/// Description of StatusService.
/// </summary>
[TestModule("########-####-####-####-############", ModuleType.UserCode, 1)]
public class StatusService : ITestModule
{
/// <summary>
/// Constructs a new instance.
/// </summary>
public StatusService()
{
// Do not delete - a parameterless constructor is required!
}
/// <summary>
/// Performs the playback of actions in this module.
/// </summary>
/// <remarks>You should not call this method directly, instead pass the module
/// instance to the <see cref="TestModuleRunner.Run(ITestModule)"/> method
/// that will in turn invoke this method.</remarks>
void ITestModule.Run()
{
Mouse.DefaultMoveTime = 300;
Keyboard.DefaultKeyPressTime = 100;
Delay.SpeedFactor = 1.0;
switch (TestSuite.CurrentTestContainer.Status)
{
case ActivityStatus.Success:
Report.Log(ReportLevel.Info, "Status Service", "The Test Case Passed. Preparing Update to #######.");
SetStatusParameter("completed", "All is well.");
break;
case ActivityStatus.Ignored:
Report.Log(ReportLevel.Info, "Status Service", "The Test Case was Ignored. Preparing Update to #######..");
SetStatusParameter("completed", string.Format("Test Case \"{0}\" was ignored.", TestSuite.CurrentTestContainer.Name));
break;
case ActivityStatus.Failed:
default:
Report.Log(ReportLevel.Info, "Status Service", "The Test Case Failed. Collecting the Reason and Preparing Update to #######..");
SetStatusParameter("error", GetFailureReason());
break;
}
}
private static void SetStatusParameter(string status, string reason)
{
var reqestString = string.Concat("{\"status\":\"", string.Format("{0}", status), "\", \"reason\":\"", string.Format("{0}", reason), "\"}");
TestSuite.CurrentTestContainer.Parameters["FinalStatus"] = reqestString;
Report.Log(ReportLevel.Info, "Status Service", "####### Status Compiled and Assigned to 'FinalStatus' Parameter.");
}
private static string GetFailureReason()
{
var rootActivity = ActivityStack.Instance.RootActivity;
var activityList = GetAllRootActivities(rootActivity).Where(
activity => !string.IsNullOrEmpty(activity.ErrorMessage) || !string.IsNullOrWhiteSpace(activity.ErrorMessage)).ToList();
var currentItem = activityList[activityList.Count - 1];
var reasonText = "''{0}'' started at ''{1}'' and has the Status: ''{2}'' because of the following error: ''{3}''";
var reason = string.Format(reasonText, TestSuite.CurrentTestContainer.Name, currentItem.BeginTime, TestSuite.CurrentTestContainer.Status.ToString(), currentItem.ErrorMessage);
Report.Log(ReportLevel.Info, "Status Service - Failure Reason", reason);
return reason;
}
private static IEnumerable<Activity> GetAllRootActivities(IActivity rootActivity)
{
var activities = new List<Activity>();
foreach (var child in rootActivity.Children)
{
var activity = child as Activity;
if (activity != null)
{
AddActivitiesRecursive(activities, activity);
}
}
return activities;
}
private static void AddActivitiesRecursive(ICollection<Activity> activities, IActivity parent)
{
foreach (var child in parent.Children)
{
var activity = child as Activity;
if (activity == null)
{
continue;
}
activities.Add(activity);
AddActivitiesRecursive(activities, activity);
}
}
}