2

I'm pretty new in testing. After some simple exercises with Visual Studio I have turned to Nunit test framework. What I'm looking for is a property or a method to use inside a [TearDown] test method that provides me a string that contains, in failure case, the error message. For example if I code this assertion:

Assert.That(true, Is.False);

then the framework gets this error message:

Message: Expected: False But was: True

What I need is the string above. Thanks.

baru
  • 401
  • 3
  • 9
  • 29
  • possible duplicate of [NUnit: Accessing the Failure Message in TearDown()](http://stackoverflow.com/questions/14340934/nunit-accessing-the-failure-message-in-teardown) – JamesT Feb 09 '15 at 10:19

2 Answers2

2

There is only one way to get an assertion failure message or an exception message... the solution is to implement an extension class! About this topic I suggest you to visit these links:

Here my code that implements the most important steps:

namespace UTExtension
{
  [ NUnitAddinAttribute(Type = ExtensionType.Core)]
  public class ExtensionToLog: IAddin, EventListener
  {

#region IAddin Members

public bool Install(IExtensionHost host)
{
  if (host == null)
    throw new ArgumentNullException("MyExtension.Install() method has failed beacuse 'host' is NULL");

  IExtensionPoint listeners = host.GetExtensionPoint("EventListeners");
  if (listeners == null)
    return false;

  listeners.Install(this);
  return true;
}

#endregion

#region Event Listener Members

/// <summary>
/// This method is executed before the TearDown test method.
/// When the test method will fail then in order to get the failure message we will use the method below. 
/// </summary>
public void TestFinished(TestResult result)
{
  if ((result.Message == null) && result.Executed && (result.ResultState == ResultState.Success))
  {
    // the single test METHOD has passed
    Console.Out.WriteLine("\t\tPassed\n");
  }
  else if(result.Message != null)
  {
    // something goes wrong
    string errorMsg = null;
    errorMsg = result.Message;
    errorMsg = Regex.Replace(errorMsg, @"\s+", " ");

    // an assert fails during the single test method
    bool assertFails= result.Executed && (result.ResultState == ResultState.Failure);
    // an exception occurrs during the single test method
    bool exeptionOccurrs = result.Executed && (result.ResultState == ResultState.Error);

    if (assertFails || exeptionOccurrs)
    {

      Console.Out.WriteLine("\t\tFailed\n");
    }
    else
    {
      // if an exception occurred during the load of the test environment
      bool loadingExeptionOccurrs = result.Executed && (result.ResultState == ResultState.Error);
      if (loadingExeptionOccurrs)
      {
          Console.Out.WriteLine("\nException --> " + errorMsg);
      }
    }

  }
}

private static bool TestMethodError = false;

/// <summary>
/// This method is executed before the FixtureTearDown test method. 
/// </summary>
public void SuiteFinished(TestResult result)
{
  // an exception occurred during the load of the test environment
  bool loadingExeptionOccurrs = result.Executed && (result.ResultState == ResultState.Failure);

  if (!loadingExeptionOccurrs || TestMethodError)
  {

  }

  TestMethodError = false; // reset the variable

}


public void RunStarted(string name, int testCount)
{
  Console.Out.WriteLine("Run has started: name= " + name + "; test count= " + testCount);
}

public void RunFinished(TestResult result)
{
  Console.Out.WriteLine("\n\nRUN HAS FINISHED: " + result.Name + " ; message: " + result.Message);
}

public void RunFinished(Exception exception)
{
  Console.Out.WriteLine("\n\nRUN HAS FINISHED: " + exception.Message);
}

public void TestStarted(TestName testName)
{
  Console.Out.WriteLine("\t\tTest method: " + testName.Name);
}
// This methos will be executed before the 'TestFixtureSetUp' method
public void SuiteStarted(TestName testName)
{
  Console.Out.WriteLine("Test Class: " + testName.Name);
}

public void UnhandledException(Exception exception)
{
  Console.Out.WriteLine("Suite has finished: " + exception.Message);
}

public void TestOutput(TestOutput testOutput)
{
}

#endregion

 }
 }

Note that if you need only one extension class then you can add it to your test assembly and you don't need to add the related dll inside the NUnit addin folder.

Community
  • 1
  • 1
baru
  • 401
  • 3
  • 9
  • 29
  • This causes problems if you are in a situation where you need NUnit Test Adapter to run tests in an unrelated project. The problem it triggers is that requiring the lib in your project plus the VS extension causes repeated unit test runs. – Erick Stone Feb 13 '16 at 01:23
0

If I am understanding your problem then you are probably looking for Assert.IsTrue(). Something like Assert.IsTrue(true, "Test Passed")

Assert.IsTrue() provides multiple overloading and gives you the option to pass an error message in case failure.See this

Secondly, You don't want to use Asserts in Teardown. You probably want to use assert in individual test instead. TearDown attribute is mostly for disposing or doing some clean up after test. Note: Don't confuse with TestFixtureTearDown. See all the assertions here

Saifur
  • 16,081
  • 6
  • 49
  • 73
  • Thanks for your reply... what I'm looking for is an object that can provide a way to get why a test method has failed. I need it because I would like to build a logger for all my tests and at the moment I can only write which test has failed (using `TestContext.CurrentContext.Result.Status` and `TestContext.CurrentContext.Test.Name` ). Now inside the `[TearDown]` method I check the resulting status: if it is `== TestStatus.Failed` then I print on a file the name of the failed test... I would like to add why it fails. That's all. – baru Feb 10 '15 at 08:53