how to intercept methods with [TestMethod()] in MSTest(unit test) project

Topics: Policy Injection Application Block
Dec 5, 2010 at 2:25 PM

In MSTest project (unit testing project created by Visual Studio), a test class is marked with [TestClass] attribute and a test method is marked with [TestMethod()] attribute, but there isn't any constructor(or caller of constructor) of a test class. Now how to use PIAB to intercept methods with [TestMethod()] attribute ?

My will is to record all of the duration of test methods, write logs, and play sound when any test method is complete.

Dec 6, 2010 at 10:23 AM

Are you referring to the actual test method or the method that being tested in the test method? Just curios on how you'll be executing your test method :-) Anyway, here are my thoughts.

For the logging, one approach I can think of is using PIAB's Logging Call Handler. Here's a reference in the documentation how you can configure a Logging Handler - http://msdn.microsoft.com/en-us/library/dd139901.aspx. Then you can do the following to intercept test methods; 

1.) Add a configuration file in your test project

2.) Configure PIAB Matching Rule (i.e Method Signature Matching Rule) and Logging Call Handler

3.)  Add Application code (PolicyInjection.Create... method). Note that the target class should be interceptable to be able to do this (either your test class or the class being tested).

And that's it. If you would want to have a customize output I would suggest to use PIAB’s Custom Handler instead - http://msdn.microsoft.com/en-us/library/dd203272.aspx . HTH

Gino Terrado
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com
 

 

Dec 6, 2010 at 7:30 PM

This isn't going to work out, unfortunately. There *is* a caller of the constructor of a test class - the MSTest framework and the test runner. There's no way I know of to hook into the construction of test class objects, so there's no opportunity to hook up interception.

 

Dec 6, 2010 at 10:01 PM
Edited Dec 6, 2010 at 10:02 PM

You can try this:

public class Tests : TestBase
{
[TestMethod]
public void Test1()
{
this.SetMethod();

Assert.IsTrue(true);
}

[TestMethod]
public void Test2()
{
this.SetMethod();

Assert.IsFalse(false);
}
}

public class TestBase
{
string method;
Stopwatch watch = new Stopwatch();

[TestInitialize]
public void TestInitialize()
{
this.watch.Start();
}

[TestCleanUp]
public void TestCleanUp()
{
long ms = this.watch.ElapsedMiliseconds;

Logger.Log(this.method + " executed in ms: " + ms);

SoundLib.PlaySound(SoundType.CowBell);
}

[MethodImpl(MethodImplOptions.NoInlining)]
protected void SetMethod()
{
method = new StackTrace().GetFrame(1).GetMethod().Name;
}
}