tags:

views:

42

answers:

3

Hello :)

I'd like to get the currently executing NUnit test in a helper method I'm using. We're actually using NUnit for integration tests here -- not unit tests. When a test finishes, we'd like to have the test clean up some log files when it's done. Currently, I've hacked around this using the StackFrame class:

class TestHelper
{
    string CurrentTestFixture;
    string CurrentTest;
    public TestHelper()
    {
        var callingFrame = new StackFrame(1);
        var method = callingFrame.GetMethod();
        CurrentTest = method.Name;
        var type = method.DeclaringType;
        CurrentTestFixture = type.Name;
    }
    public void HelperMethod()
    {
        var relativePath = Path.Combine(CurrentTestFixture, CurrentTest);
        Directory.Delete(Path.Combine(Configurator.LogPath, relativePath));
    }
}

[TestFixture]
class Fix
{
    [Test]
    public void MyTest()
    {
        var helper = new TestHelper();
        //Do other testing stuff
        helper.HelperMethod();
    }
    [Test]
    public void MyTest2()
    {
        var helper = new TestHelper();
        //Do some more testing stuff
        helper.HelperMethod();
    }
}

This works just fine, except there are cases where I'd like to make the TestHelper class part of my fixture, like this:

[TestFixture]
class Fix
{
    private TestHelper helper;

    [Setup]
    public void Setup()
    {
        helper = new TestHelper();
    }

    [TearDown]
    public void TearDown()
    {
        helper.HelperMethod();
    }

    [Test]
    public void MyTest()
    {
        //Do other testing stuff
    }
    [Test]
    public void MyTest2()
    {
        //Do some more testing stuff
    }
}

I can't simply make this class into a global fixture because sometimes a single test will use it more than once, and sometimes a test need not use it at all. Sometimes a test needs to attach specific properties to the TestHelper.... things like that.

As a result, I'd like to be able to somehow get the currently executing test without having to manually repeat the name of the fixture and test in the several thousand test cases I'm looking at.

Is there a way to get such information?

A: 

Moving the code you have in the TestHelper constructor to the HelperMethod would do the trick for you?

class TestHelper
{
    public void HelperMethod()
    {
        string CurrentTestFixture;
        string CurrentTest;

        var callingFrame = new StackFrame(1);
        var method = callingFrame.GetMethod();
        CurrentTest = method.Name;
        var type = method.DeclaringType;
        CurrentTestFixture = type.Name;

        var relativePath = Path.Combine(CurrentTestFixture, CurrentTest);
        Directory.Delete(Path.Combine(Configurator.LogPath, relativePath));
    }
}
smink
No, because the helper method is being called in the TearDown in my example. That said, I have vastly simplified things here. The real helper class does things like specifying assertions on output... etc. and more than one method needs to be called inside of it.
Billy ONeal
A: 

By the looks is that you can't because the stack frame at the point of setup and teardown does not include the test method.

As for cleaning up log files it looks like you want to have a log file per test method. Perhaps in this case it might be better to either:

  1. Use a random id as part of the log file name which you can clean up in the teardown of the helper class. If however the name of the test method is required to be part of the log file you could do..
  2. You can implement IDisposable todo the cleanup

    [Test]
    public void MyTest()
    {
        using(new TestHelper())
        {
            ... test goes here ...
        }
    }
    
  3. Or use PostSharp to weave the above code as part of an attribute on your test method.

    [Test, TestHelper]
    public void MyTest()
    {
       ...
    }
    

[EDIT]

fixed formatting. Added IDisposable

aqwert
P.S.the code formatting is screwing with me
aqwert
@aqwert: That's just the simple example I cobbled together here. The real test class can't be done that way because I need to be able to access it to add things from within the test. The goal is to eliminate the stack frame hack I'm currently using, not to fix it.
Billy ONeal
+1  A: 

NUnit 2.5.7 has added an "experimental" TestContext class. One of the properties it contains is TestName. I haven't tried it, so I don't know whether the info is available in the TearDown method.

Pedro