In couple of my previous posts, I talked about what are the important events raised by test management service and how code for one such event listener looks like. In this post, I will talk about what exact steps I did to write my test management event listener. In case you are interested in writing one for your needs, you can follow similar steps.
Problem I need to solve
I want to find out all the test suites that are getting changed in my project, who is changing them and at what time they are getting changed. The changes in the suites could be of any form like creation of a new sub-suite, deletion of a sub-suite, addition/removal of tests in a suite etc.
Which event could help?
For the above problem, I looked at the important events which are exposed by the server, studied all of them and concluded that I need to listen to TestSuiteChangedNotification as it is raised when-ever a test suite is changed.
Writing the listener
Let us start with the main steps that I followed to create my listener.
Note: – The first 2 binaries are not present with the Visual Studio installation, so I had to copy it from my team foundation server installation.
public Type[] SubscribedTypes() { return new Type[] { typeof(TestSuiteChangedNotification) }; }
public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties) { … // Not a notification => no need to do anything if (notificationType != NotificationType.Notification) { return EventNotificationStatus.ActionPermitted; }
public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties) { …
// Not a notification => no need to do anything if (notificationType != NotificationType.Notification) { return EventNotificationStatus.ActionPermitted; }
// no suite change notification => no need to do anything TestSuiteChangedNotification suiteChangedNotification = notificationEventArgs as TestSuiteChangedNotification; if (suiteChangedNotification == null) { return EventNotificationStatus.ActionPermitted; }
// if parameters are not valid => no need to do anything if (string.IsNullOrEmpty(suiteChangedNotification.ProjectName) || suiteChangedNotification.SuiteId <= 0) { return EventNotificationStatus.ActionPermitted; }
/// <summary> /// Get the tfs collection url /// </summary> private static string GetCollectionUrl(TeamFoundationRequestContext requestContext) { TeamFoundationLocationService locationService = requestContext.GetService<TeamFoundationLocationService>(); return locationService.GetHostLocation(requestContext, locationService.GetServerAccessMapping(requestContext)); }
using (TfsTeamProjectCollection collection = new TfsTeamProjectCollection(new Uri(collectionurl))) { ITestManagementService tcm = collection.GetService<ITestManagementService>(); ITestManagementTeamProject project = tcm.GetTeamProject(projectName);
ITestSuiteBase suite = project.TestSuites.Find(suiteId);
string message = string.Format("Suite '{0}' (Id={1} under plan '{2}' in project '{3}') was modified by {4} at {5}", suite.Title, suite.Id, suite.Plan.Name, projectName, suite.LastUpdatedByName, suite.LastUpdated); TeamFoundationApplication.Log(message, 123, System.Diagnostics.EventLogEntryType.Information);
This completes the implementation of the interface.
This completes the development and deployment. Now I tried changing few things in my suites and observed that corresponding events are getting logged in the server event logs.
Thanks for reading and looking forward to your real custom listeners.
Here is the complete sample code along with the binaries just in case you want to use to get started on it quickly. Note that this sample will work only on Tfs 2012 server.
- Aseem Bansal