5

大家好,我有一个关于 NUnit 扩展(2.5.10)的问题。我想要做的是向数据库写入一些额外的测试信息。为此,我使用事件侦听器创建了 NUnit 扩展。我遇到的问题是 public void TestFinished(TestResult result) 方法在运行时被调用了两次。我写入数据库的代码就是这种方法,这让我在数据库中留下了重复的条目。问题是:这是预期的行为吗?我能做点什么吗?扩展代码如下。谢谢。

using System;
using NUnit.Core;
using NUnit.Core.Extensibility;

namespace NuinitExtension
{
[NUnitAddinAttribute(Type = ExtensionType.Core,
                     Name = "Database Addin", 
                     Description = "Writes test results to the database.")]
public class MyNunitExtension : IAddin, EventListener
{
    public bool Install(IExtensionHost host)
    {
        IExtensionPoint listeners = host.GetExtensionPoint("EventListeners");
        if (listeners == null)
            return false;

        listeners.Install(this);
        return true;
    }

    public void RunStarted(string name, int testCount){}
    public void RunFinished(TestResult result){}
    public void RunFinished(Exception exception){}
    public void TestStarted(TestName testName){}

    public void TestFinished(TestResult result)
    {
        // this is just sample data
        SqlHelper.SqlConnectAndWRiteToDatabase("test", test", 
                                               2.0, DateTime.Now);
    }

    public void SuiteStarted(TestName testName){}
    public void SuiteFinished(TestResult result){}
    public void UnhandledException(Exception exception){}
    public void TestOutput(TestOutput testOutput){}
}

}

4

2 回答 2

1

我已经设法通过从 NUnit 2.5.10\bin\net-2.0\addins 文件夹中删除我的扩展程序集来解决这个问题。目前一切都按预期工作,但我不确定如何。我认为您必须在 addins 文件夹中有扩展/插件程序集。我通过 NUnit.exe 打开解决方案来运行测试。我的扩展项目是我正在测试的解决方案的一部分。我也向 NUnit 的人提出了这个问题,并得到了以下解释:

很可能,您的插件被加载了两次。为了更容易测试插件,除了搜索插件目录之外,NUnit 还在每个测试程序集中搜索要加载的插件。通常,当您确信您的插件可以正常工作时,您应该将其从测试程序集中删除并将其安装在插件文件夹中。这使它可用于使用 NUnit 运行的所有测试。OTOH,如果您真的只希望插件申请某个项目,那么您可以将其留在测试程序集中,而不是将其安装为永久插件。 http://groups.google.com/group/nunit-discuss/browse_thread/thread/c9329129fd803cb2/47672f15e7cc05d1#47672f15e7cc05d1

于 2011-07-13T07:58:47.113 回答
0

不确定这个答案是否严格相关,但可能有用。

我最近在玩 NUnit 库来阅读 NUnit 测试,以便可以轻松地将它们转移到我们自己的内部验收测试框架中。

事实证明,我们可能不会坚持这一点,但认为分享我弄清楚如何使用 NUnit 代码的经验可能会很有用:

不同之处在于它不是由 NUnit 控制台或 Gui Runner 运行,而是由我们自己的控制台应用程序运行。

public class NUnitTestReader
{
    private TestHarness _testHarness;

    public void AddTestsTo(TestHarness testHarness)
    {
        _testHarness = testHarness;
        var package = new TestPackage(Assembly.GetExecutingAssembly().Location){AutoBinPath = true};
        CoreExtensions.Host.InitializeService();
        var testSuiteBuilder = new TestSuiteBuilder();
        var suite = testSuiteBuilder.Build(package);

        AddTestsFrom(suite);
    }

    private void AddTestsFrom(Test node)
    {
        if (!node.IsSuite)
            AddTest(node);
        else
        {
            foreach (Test test in node.Tests)
                AddTestsFrom(test);
        }
    }

    private void AddTest(Test node)
    {
        _testHarness.AddTest(new WrappedNUnitTest(node, TestFilter.Empty));
    }
}

上面从当前程序集中读取 NUnit 测试,将它们包装起来,然后将它们添加到我们的内部测试工具中。我没有包含这些类,但它们对于理解 NUnit 代码的工作原理并不重要。

这里真正有用的信息是“InitialiseService”的静态信息,这需要花费很多时间才能弄清楚,但对于在 NUnit 中加载基本的测试阅读器集是必要的。在查看 NUnit 中的测试时需要小心一点,因为它包括失败的测试(由于涉及的静态数量,我认为它不起作用) - 所以看起来有用的文档实际上是误导性的。

除此之外,您还可以通过实现 EventListener 来运行测试。我对在我们的测试和 NUnit 测试之间建立一对一的映射很感兴趣,因此每个测试都是独立运行的。为此,您只需要实现 TestStarted 和 TestFinished 即可进行日志记录:

    public void TestStarted(TestName testName)
    {

    }
    public void TestFinished(TestResult result)
    {
        string text;
        if (result.IsFailure) 
            text = "Failure";
        else if (result.IsError)
            text = "Error";
        else
            return;

        using (var block = CreateLogBlock(text))
        {
            LogFailureTo(block);
            block.LogString(result.Message);
        }
    }

这种方法有几个问题: 从其他程序集继承的测试基类,使用委托给当前程序集中的方法的 SetUp 方法不会被调用。它也有 TestFixtureSetup 方法的问题,这些方法仅在 TestSuites 运行时在 NUnit 中调用(而不是单独运行测试方法)。

这些似乎都是 NUnit 的问题,但如果您不想单独构建包装测试,我认为您可以调用 suite.Run 并使用适当的参数,这将解决后一个问题

于 2012-03-26T17:01:46.583 回答