ASP.Net 中的 NUnit 引擎

NUnit Engine in ASP.Net

下午好,

对于我当前的项目,我正在尝试创建一个将托管在我们的开发服务器中的 NUnit Runner。 对于快速版本,我使用 ASP.NET Webforms + 来自 NuGet 的最新版本的 NUnit(当前为 3.4.1,引擎 + 核心)。我正在遵循此 中关于如何 运行 从代码进行测试的建议。

加载我的应用程序时出现以下异常:

Could not load file or assembly 'nunit.framework' or one of its dependencies. The system cannot find the file specified.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.IO.FileNotFoundException: Could not load file or assembly 'nunit.framework' or one of its dependencies. The system cannot find the file specified.

Source Error: 
Line 33:             {
Line 34:                 // execute the tests            
Line 35:                 XmlNode result = runner.Run(null, emptyFilter);
Line 36:                 lblTest.Text = result.InnerText;
Line 37:             }

我的 NUnit 库位于 Web 应用程序的 Binary 文件夹中,所以我不知道为什么无法从那里找到 'nunit.framework'。

这是我用于 运行ner 的实际代码:

using NUnit.Engine;
using NUnit.Framework;
using System;
using System.Reflection;
using System.Xml;

namespace NunitWebRunner
{
    public partial class _default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // set up the options
            string path = Assembly.GetExecutingAssembly().Location;
            TestPackage package = new TestPackage(path);
            package.AddSetting("WorkDirectory", Environment.CurrentDirectory);

            // prepare the engine
            ITestEngine engine = TestEngineActivator.CreateInstance();
            var _filterService = engine.Services.GetService<ITestFilterService>();
            ITestFilterBuilder builder = _filterService.GetTestFilterBuilder();
            TestFilter emptyFilter = builder.GetFilter();

            using (ITestRunner runner = engine.GetRunner(package))
            {
                // execute the tests            
                XmlNode result = runner.Run(null, emptyFilter);
                lblTest.Text = result.InnerText;
            }
        }
    }

    [TestFixture]
    public class TemplateTestClass
    {
        [Test]
        public void TestThatPasses()
        {
            Assert.IsTrue(true);
        }

        [Test]
        public void TestThatFails()
        {
            Assert.AreEqual(4, 5);
        }

        [Test]
        [Ignore("Ignored")]
        public void IgnoredeTest()
        {
            Assert.IsTrue(false);
        }
    }
}

知道发生了什么,或者我如何尝试修复它以使其正常工作?

重复我在 nunit-discuss 列表中的回答,其中的问题 post 编辑时间与此处大致相同。 @Glenn Rodriguez 这样的 multi-posting 在很多圈子里被认为是粗鲁的。它迫使我们这些回答的人做双重工作,以便看到问题的人也能够找到答案。


“作为第一个问题......你是想创建一个 运行ner 还是你 只是想要一个自动执行的测试?您的示例是一个自动执行的 测试,但也许您只是为了举例而这样做。 如果你想要的只是一个自执行测试,那么我们有 NUnitLite 完全按照您的示例显示。

“OTOH,如果你正在创建自己的 运行ner,你应该使用引擎 正如你所做的那样。 (您链接的 SO 问题中的第二种方法 是错误的 - 它可以在简单的情况下工作,但会 运行 成为问题 最终因为那不是控制台 运行ner 的设计目的 对于。)

“你的代码可以更简单 wrt 过滤器。只需使用 TestFilter.Empty 当运行完成所有测试时。

“您的测试包使用所有默认设置,除了 工作目录。这意味着 NUnit 将尝试 运行 通过创建你的测试 一个单独的进程并使用 NUnit 测试代理启动它。这个 可能不是你想要的。使用 "ProcessModel" 设置 "Single" 到 运行 当前进程中的测试。您可能还需要一个 "DomainUsage" 设置 "None" 如果你不想让 NUnit 创建一个 测试的单独域。两种方式都试试。

"Good luck!"


我将添加一些进一步的评论...

您链接的 SO post 中建议的第一种方法想法正确但不完整,因为它完全依赖于引擎的默认设置。

建议的第二种方法似乎有效,直到您尝试在同一个程序中多次 运行。控制台 运行ner Main 不打算被称为 Main 以外的任何东西。

当你问一个关于你正在做的不寻常的事情时,如果你能解释你为什么这样做,通常会帮助人们帮助你。

经过 Nunit-Dicussion Group 中的讨论,这个问题的解决方案非常简单。

查理在上面评论说,问题出在代码中使用的当前配置上。应该设置 "ProcessModel" 和 "DomainUsage" 而不是使用 "WorkingDirectory",这样 NUnit runner 可以在像 ASP.NET.

这样的 Web 环境中毫无问题地执行

您可以在下面找到将此线程标记为已回复的代码。

using NUnit.Engine;
using NUnit.Framework;
using System;
using System.Reflection;
using System.Xml;

namespace NunitWebRunner
{
    public partial class _default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // set up the options
            string path = Assembly.GetExecutingAssembly().Location;
            TestPackage package = new TestPackage(path);
            package.AddSetting("ProcessModel", "Single");
            package.AddSetting("DomainUsage", "None");

            // prepare the engine
            ITestEngine engine = TestEngineActivator.CreateInstance();
            var _filterService = engine.Services.GetService<ITestFilterService>();
            ITestFilterBuilder builder = _filterService.GetTestFilterBuilder();
            TestFilter emptyFilter = builder.GetFilter();

            using (ITestRunner runner = engine.GetRunner(package))
            {
                // execute the tests            
                XmlNode result = runner.Run(null, emptyFilter);
                lblTest.Text = result.InnerText;
            }
        }
    }

    [TestFixture]
    public class TemplateTestClass
    {
        [Test]
        public void TestThatPasses()
        {
            Assert.IsTrue(true);
        }

        [Test]
        public void TestThatFails()
        {
            Assert.AreEqual(4, 5);
        }

        [Test]
        [Ignore("Ignored")]
        public void IgnoredeTest()
        {
            Assert.IsTrue(false);
        }
    }
}