且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

NUnit-测试失败后进行清理

更新时间:2022-03-12 23:24:23

这个想法引起了我的兴趣,因此我做了一些深入的研究。 NUnit没有开箱即用的功能,但是NUnit提供了一个完整的可扩展性框架。我发现这篇关于扩展NUnit的伟大文章-这是一个很好的起点。经过测试之后,我想出了以下解决方案:如果夹具中的一项测试失败,则将调用一个用自定义 CleanupOnError 属性修饰的方法。

This idea got me interested, so I did a little digging. NUnit doesn't have this ability out of the box, but there is a whole extensibility framework supplied with NUnit. I found this great article about extending NUnit - it was a good starting point. After playing around with it, I came up with the following solution: a method decorated with a custom CleanupOnError attribute will be called if one of the tests in the fixture failed.

这是测试的样子:

  [TestFixture]
  public class NUnitAddinTest
  {
    [CleanupOnError]
    public static void CleanupOnError()
    {
      Console.WriteLine("There was an error, cleaning up...");
      // perform cleanup logic
    }

    [Test]
    public void Test1_this_test_passes()
    {
      Console.WriteLine("Hello from Test1");
    }

    [Test]
    public void Test2_this_test_fails()
    {
      throw new Exception("Test2 failed");
    }

    [Test]
    public void Test3_this_test_passes()
    {
      Console.WriteLine("Hello from Test3");
    }
  }

其中的属性很简单:

  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class CleanupOnErrorAttribute : Attribute
  {
  }

这是从插件执行的方式:

And here is how it's executed from the addin:

public void RunFinished(TestResult result)
{
  if (result.IsFailure)
  {
    if (_CurrentFixture != null)
    {
      MethodInfo[] methods = Reflect.GetMethodsWithAttribute(_CurrentFixture.FixtureType,
                                                             CleanupAttributeFullName, false);
      if (methods == null || methods.Length == 0)
      {
        return;
      }

      Reflect.InvokeMethod(methods[0], _CurrentFixture);
    }
  }
}

但这是棘手的部分:插件必须放置在NUnit运行器旁边的 addins 目录中。矿井位于TestDriven.NET目录中的NUnit运行器旁边:

But here's the tricky part: the addin must be placed in the addins directory next to the NUnit runner. Mine was placed next to the NUnit runner in TestDriven.NET directory:


C:\Program Files\ TestDriven.NET 2.0\NUnit\addins

(我创建了插件目录,它不在那里)

(I created the addins directory, it wasn't there)

编辑另一件事是,清理方法需要 static

EDIT Another thing is that the cleanup method needs to be static!

我砍在一起是一个简单的插件,您可以从我的SkyDrive 。您将必须添加对 nunit.framework.dll nunit.core.dll nunit.core.interfaces.dll 放在适当的位置。

I hacked together a simple addin, you can download the source from my SkyDrive. You will have to add references to nunit.framework.dll, nunit.core.dll and nunit.core.interfaces.dll in the appropriate places.

一些注意事项:属性类可以放在代码中的任何位置。我不想将其与插件本身放置在同一程序集中,因为它引用了两个 Core NUnit程序集,因此我将其放置在其他程序集中。如果您决定将它放置在其他任何地方,只需记住在 CleanAddin.cs 中更改该行即可。

A few notes: The attribute class can be placed anywhere in your code. I didn't want to place it in the same assembly as the addin itself, because it references two Core NUnit assemblies, so I placed it in a different assembly. Just remember to change the line in the CleanAddin.cs, if you decide to put it anywhere else.

希望会有所帮助。