views:

442

answers:

6

At my company we are writing a bunch of unit tests. What we'd like to have done is for the unit tests to execute and whenever one succeeds or fails at the end of the test we can write that somewhere but we don't want to put that logic in every test.

Any idea how we could just write tests without having to surround the content of the test with the try catch logic that we've been using?

+2  A: 

MSTest has TestCleanup, which runs after every test. In NUnit, the attribute to be used is TearDown (after every test) or TestFixtureTearDown (after all the test are completely). This executes after the end of each test.

If you want something to run just in case a test passes, you could have a member variable shouldRunExtraMethod, which is initialized to false before each test, and is changed to true at the end of the test. And on the TearDown, you only execute it depending on this variable value

Samuel Carrijo
A: 

NUnit assert statements all have an option to print a message for each test for when it fails.

Although if you'd like to have it write out something somewhere at the end of each test, you can set it up in the teardown of each method. Just set the string to what you want written inside the test itself, and during teardown (which happens after each test) It can do whatever you want with it.

I'm fairly certain teardown occurs even if an exception is thrown. That should do what you're wanting.

Kurisu
+2  A: 

I'm not entirely sure what you are trying to do here. Are you saying you are wrapping it in a try/catch so that you can catch when an exception occurs and log this? If so, then a better way, probably, is just to get NUnit to write an output file and use this. I haven't used NUnit for about a year, but IIRC you can redirect its output to any file you like using the /out directive.

If there is a reason why you have to log it the way you say, then you'll either have to add your custom code to each test, or have a common "runner" that takes your code (for each test) as an anonymous method and runs it inside a single try..catch. That would prevent you having to repeat the try..catch for every test.

Apologies if I've misunderstood the question.

Rob Levine
+2  A: 

I'm guessing you do something like this:

[Test]
public void FailBecauseOfException()
{
   try
   {
      throw new Exception();
   }
   catch (Exception e)
   {
      Assert.Fail(e.Message);
   }
}

There is no need for this. The tests will fail automatically if they throw an exception. For example, the following test will show up as a failure:

[Test]
public void FailBecauseOfException()
{
   throw new Exception();
}
Wim Coenen
+1  A: 

If your unit test method covers the scenario in which you expect exceptions to be thrown, use the ExpectedException attribute. There's a post here on SO about using that attribute.

Expect exceptions in nUnit...

mqbt
A: 

Hi there.

The problem you have is that the NUnit Assert.* methods will throw an AssertionException whenever an assert fails - but it does nothing else. So it doesn't look like you can check anything outside of the unit test to verify whether the test failed or not.

The only alternative I can think of is to use AOP (Aspect Oriented Programming) with a tool such as PostSharp. This tool allows you to create aspects that can act on certain events. For example:

public class ExceptionDialogAttribute : OnExceptionAspect
{
  public override void OnException(MethodExecutionEventArgs eventArgs)
  {
    string message = eventArgs.Exception.Message;
    Window window = Window.GetWindow((DependencyObject) eventArgs.Instance);
    MessageBox.Show(window, message, "Exception");
    eventArgs.FlowBehavior = FlowBehavior.Continue;
  }
}

This aspect is code which runs whenever an exception is raised:

[ExceptionDialog]
[Test]
public void Test()
{
    assert.AreEqual(2, 4);
}

Since the above test will raise an exception, the code in ExceptionDialogAttribute will run. You can get information about the method, such as it's name, so that you can log it into a file.

It's been a long time since I used PostSharp, so it's worth checking out the examples and experimenting with it.

Cheers. Jas.

Jason Evans