我们有一些关测试,访问该数据库。当他们中的一个失败,它可以让数据库的不一致状态-这是不是一个问题,因为我们重建数据库对每一个测试运行,但它可能会导致其他的测试失败,在相同的运行。

是它可以检测到,其中一项测试失败和执行某些清理?

我们不希望写清理代码在每一个测试,我们已经这样做了,现在。我想向执行清除在拆除,但只有当的测试失败了,因为清理可能是昂贵的。

更新:澄清-我想测试,以简单并不包括任何清理或错误的处理逻辑。我也不想执行数据库的重置在每个试验运行的,如果只考试失败。和这个代码也许应该执行的拆除方法,但是我不知道任何方式获得的信息,如果测试我们目前正在撕裂下来的失败或成功。

Update2:

        [Test]
        public void MyFailTest()
        {
            throw new InvalidOperationException();
        }

        [Test]
        public void MySuccessTest()
        {
            Assert.That(true, Is.True);
        }

        [TearDown]
        public void CleanUpOnError()
        {
            if (HasLastTestFailed()) CleanUpDatabase();
        }

我正在寻找执行HasLastTestFailed()

有帮助吗?

解决方案

这个想法让我感兴趣,所以我做了一点挖掘。关没有这种能力,但有一个整体的扩展框架提供有呢?我找到了 这个伟大的条约的延伸呢 -这是一个良好的起点。后玩弄了,我提出了以下方案:一个方法装饰的一个自定义 CleanupOnError 属性将被称为如果一个测试在固定装置失败。

这里是如何测试的样子:

  [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
  {
  }

这里是它是如何执行从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);
    }
  }
}

但这是最棘手的部分:该addin必须被放置在 addins 目录旁边的呢亚军。我是旁边的呢亚军TestDriven.NET 目录:

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

(我创造的 addins 目录,它不在那儿)

编辑 另一件事是清除方法需要 static!

我砍死在一起的一个简单的马吉德,你可以下载源 我的网盘.你将不得不增加引用 nunit.framework.dll, nunit.core.dllnunit.core.interfaces.dll 在适当的地方。

几点注意事项:属性类可以在任何地方放置在你的代码。我不想把它放在同一会作为addin本身,因为它引用两个 Core 关组件,所以我把它放在一个不同的组件。只记得改变行 CleanAddin.cs, 如果你决定要把它放其他地方。

希望这有所帮助。

其他提示

由于2.5.7版本,NUnit的允许拆卸,以检测是否最后测试失败。 一种新的TestContext类允许测试访问关于他们自己的信息,包括TestStauts。

有关详情,请参阅 http://nunit.org/?p=releaseNotes&r = 2.5.7

[TearDown]
public void TearDown()
{
    if (TestContext.CurrentContext.Result.Status == TestStatus.Failed)
    {
        PerformCleanUpFromTest();
    }
}

虽然有可能强迫NUnit的成这样是不是最明智的设计,你总是可以设置临时文件的地方,如果该文件存在,运行清理。

我建议改变你的代码,以便您已经启用了数据库事务,并在测试结束时,只需要将其还原数据库到原来的状态(例如丢弃代表您的单元测试的交易)。

是,有。可以使用的 拆卸属性其中每次测试后,将拆毁。你要应用数据库“复位”,你必须和拆卸和重新安装前和每次测试后,脚本

  

此属性内的使用   的TestFixture提供一组通用的   被后执行的功能   每个测试方法被运行。

更新:根据的评论和更新的问题,我说你可以使用拆卸属性和使用私有变量,以表明该方法的内容是否应该解雇。

不过,我还没有看到你不希望任何复杂的逻辑或错误处理代码。

鉴于这种情况,我认为一个标准设置/ 拆卸将工作最适合你。如果有错误,你不必有任何的错误处理代码没关系。

如果您需要特殊的清理,因为接下来的测试取决于当前测试的成功完成,我建议重新审视你的测试 - 他们可能不应该是互相依赖的。

有关使用try-catch块,重新抛出捕捉到的异常什么?

try
{
//Some assertion
}
catch
{
     CleanUpMethod();
     throw;
}

我不喜欢PHSR建议现在,当你能负担得起,重构测试,让他们永远不必依赖于相同的数据的另一个测试需求,甚至更好的抽象的数据访问层和模拟结果来自何处该数据库。这听起来像你的测试是相当昂贵的,你,你应该做你的装配数据库和业务逻辑,你真的不关心结果被返回是什么,你的所有查询逻辑。

您还可以测试你的ExceptionHandling好多了。

另一种选择是有一个特殊的功能,将你抛出异常,在那个说,一个出现异常的的TestFixture设置一个开关。

public abstract class CleanOnErrorFixture
{
     protected bool threwException = false;

     protected void ThrowException(Exception someException)
     {
         threwException = true;
         throw someException;
     }

     protected bool HasTestFailed()
     {
          if(threwException)
          {
               threwException = false; //So that this is reset after each teardown
               return true;
          }
          return false;
     }
}

然后,使用您的示例:

[TestFixture]
public class SomeFixture : CleanOnErrorFixture
{
    [Test]
    public void MyFailTest()
    {
        ThrowException(new InvalidOperationException());
    }

    [Test]
    public void MySuccessTest()
    {
        Assert.That(true, Is.True);
    }

    [TearDown]
    public void CleanUpOnError()
    {
        if (HasLastTestFailed()) CleanUpDatabase();
    }
}

这里唯一的问题是,堆栈跟踪将导致CleanOnErrorFixture

它是如何失败?是否有可能把它放在一试(做测试)/捕捉(破镜重圆DB)/ finally块?

或者你可以调用一个私有方法来解决它,当您检查您的故障状态。

我并不是说这是一个好主意,但它应该工作。 请记住,断言失败只是例外。也不要忘记还有运行只有一次在灯具的所有测试都运行后[TestFixtureTearDown]属性。

使用这两个事实,你可以写的东西,如设置一个标志,如果一个测试失败,检查测试夹具的标志的值推倒。

我不建议这样做,但它会工作。你是不是真的使用NUnit如预期,但你可以做到这一点。


[TestFixture]
public class Tests {
     private bool testsFailed = false;

     [Test]
     public void ATest() {
         try {
             DoSomething();
             Assert.AreEqual(....);
         } catch {
            testFailed = true;
         }
     }

     [TestFixtureTearDown]
     public void CleanUp() {
          if (testsFailed) {
              DoCleanup();
          }
     }
}

可以添加与点击一个[TearDown]方法 if (TestContext.CurrentContext.Result.Status != TestStatus.Passed)结果 如果测试失败,以执行一些代码。

scroll top