【问题标题】:NUnit extensionNUnit 扩展
【发布时间】:2013-01-08 04:02:30
【问题描述】:

大家好,我有一个关于 NUnit 扩展 (2.5.10) 的问题。 我想做的是向 数据库。为此,我使用 Event 创建了 NUnit 扩展 听众。 我遇到的问题是公共无效 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){}
}

}

【问题讨论】:

  • 我认为TestFinished 每次测试至少会被调用一次。你只运行一个测试吗?如果您是,那么可能会为夹具调用一次TestFinished,并为测试方法调用一次。我很长时间没有查看 NUnit 代码,所以我不能 100% 确定。您应该可以通过检查传入的TestResult 上的属性来判断。
  • 谢谢迈克,我正在运行多个测试,我确实想记录每一个测试,但只记录一次,相反,我为每个测试获得两个条目。而且我认为这个特定的方法只会为每个测试运行一次,SuiteStarted 将为每个 TestFixture 运行。
  • 套件不同。有一种设置套件的显式方法。我从不使用它,所以我不知道怎么用了。 TestResult 遵循复合模式。所以它可能是测试或夹具或整个测试运行的结果。令我惊讶的是,一次测试调用了两次。会不会安装了两次?
  • 它没有安装两次,只是检查了一下。我刚刚尝试使用以下设置运行测试:[Setup]、[Teardown]、[Test] 和 TestFinished 再次被调用两次,原因不明。

标签: nunit nunit-2.5


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    我最近在玩 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 并使用适当的参数,这将解决后一个问题

    【讨论】:

      猜你喜欢
      • 2017-11-30
      • 2015-06-03
      • 2023-03-06
      • 1970-01-01
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多