0

我正在使用 NUnit 2.X 库,但现在想使用 NUnit 3.X。我有一些关于从 2.X 迁移到 3.X 的问题。首先我有一个设置夹具类。这是2.X版本;

using System;
using System.IO;
using System.Reflection;
using HalisEnerji.QuantSignal.Logging;
using NUnit.Framework;

namespace HalisEnerji.QuantSignal.Tests
{
    [SetUpFixture]
    public class Initialize
    {
        [SetUp]
        public void SetLogHandler()
        {
            Log.LogHandler = new ConsoleLogHandler();
        }
    }
}

第一个问题是通过使用“OneTimeSetUp”属性更改“Setup”属性来解决的。通过为设置测试目录添加一些代码解决了第二个问题。因为我正在使用 Re-Sharper 测试引擎。这是安装夹具的最终形状;

using System;
using System.IO;
using System.Reflection;
using HalisEnerji.QuantSignal.Logging;
using NUnit.Framework;

namespace HalisEnerji.QuantSignal.Tests
{
    [SetUpFixture]
    public class Initialize
    {
        [OneTimeSetUp]
        public void SetLogHandler()
        {
            Log.LogHandler = new ConsoleLogHandler();

            var assembly = Assembly.GetExecutingAssembly();
            var localPath = new Uri(assembly.CodeBase).LocalPath;
            var direcotyName = Path.GetDirectoryName(localPath);
            if (direcotyName != null)
            {
                Environment.CurrentDirectory = direcotyName;
            }
        }
    }
}

在解决了设置夹具问题之后,我真正的问题开始于使用 TestCaseSource/TestCaseData。这是示例 2.X 版本;

[Theory]
[TestCaseSource("CreateSymbolTestCaseData")]
public void CreateSymbol(string ticker, Symbol expected)
{
    Assert.AreEqual(Symbol.Create(ticker), expected);
}

private TestCaseData[] CreateSymbolTestCaseData()
{
    return new []
    {
        new TestCaseData("SPY", new Symbol(Security.GenerateEquity("SPY"), "SPY")),
        new TestCaseData("EURUSD", new Symbol(Security.GenerateForex("EURUSD"), "EURUSD"))
    };
}

2.X 版本创建异常,我的测试失败。很快异常告诉 TestCaseData 提供者方法必须是静态的。好吧,在使用静态标识符测试的标记方法正常工作之后,但这次我的其他测试失败了(在使用静态标识符之前它没有失败)。为什么我的其他测试失败了?因为它正在从测试目录读取文件,并在设置夹具代码运行和更改测试目录之前以某种方式测试工作!

在使用静态标识符之前,首先运行 SetUpFixture 代码,然后运行测试代码。在使用静态标识符顺序更改我的测试后,在 SetUpFixture 代码运行后首先运行从测试目录(这是 Re-Sharper 的临时目录且不包含必要文件)读取文件的测试。知道我的所有测试如何成功吗?

更新:

解释一些单位;

  1. 我有 Initialize.cs(我的测试程序集的一部分),它负责设置 CurrentDirectory。
  2. 我有 Config.cs(我的项目基础结构程序集的一部分),它是我的项目配置文件,它有 public static readonly Setttings 属性,它正在从 CurrentDirectory 读取配置文件。
  3. 我有 ConfigTests.cs(我的测试程序集的一部分),其中包含一些用于读/写 Settings 属性的测试方法。

当我调试测试时;

  1. 在使用任何静态 TestCaseSource 之前,它们按顺序工作;

A. Initialize.cs => 设置方法

B. Config.cs => 静态设置属性getter方法

C. ConfigTests.cs => 第一个测试方法

因此,首先初始化工作,其他人稍后工作,所有测试都成功通过了测试。

  1. 在其他测试文件中使用静态 TestCaseSource 之后,可以说 OrdersTests.cs(从项目中排除,之后再次包含第一个场景),不知何故,工作顺序正在改变,如下所示;

A. Config.cs => 静态设置属性getter方法

B. OrdersTests.cs => 静态 TestCaseSource 方法(不是测试方法)

C. Initialize.cs => 设置方法

D. ConfigTests.cs => 第一个测试方法

E. OrdersTests.cs => 第一个测试方法

因此,我的 ConfigTests.cs 测试失败,因为 Initialize.cs 在 Config.cs 之后工作。我希望通过此更新,我的问题更加清晰。

这个问题与 NUnit 或 Resharper 或 V.Studio 有关吗?我不知道,我只知道我成功通过的测试现在失败了!

更新 2:

克里斯,

是的你是对的。我详细探索了项目,我发现问题与我的项目的一些类访问静态 Config 类及其静态 Settings 属性有关(在运行测试设置夹具方法之前,甚至在静态测试用例源方法之前!)。您谈到测试方法的过程顺序;NUnit 像你说的那样做测试,而不是像我说的那样。但是当我尝试使用您的解决方案时(在测试用例源之前设置当前目录)它不起作用。因此,我以另一种方式解决了我的问题。我不高兴,但至少我的测试方法现在有效。您能否告诉我在初始化/设置方法之前运行静态测试用例方法的技术原因是什么?这是因为 NUnit 还是因为 .Net Framework 的基础设施?我对 NUnit 和/或 TDD 并不狂热。我不

感谢您的关注。

4

1 回答 1

2

因为它正在从测试目录读取文件,并在设置夹具代码运行和更改测试目录之前以某种方式测试工作!

你是如何阅读这个文件的?您应该TestContext.CurrentContext.TestDirectory在 NUnit 3 中使用来获取测试目录,而不是依赖当前目录的位置。有关详细信息,请参阅重大更改页面。

编辑:我还看到您已标记此 ReSharper 7.1。您应该知道,此版本的 resharper 不支持 NUnit 3 - 第一个支持的版本是 ReSharper 10。您的测试似乎运行正常 - 但是您可能会遇到奇怪的副作用,这可能会在任何未来版本的 NUnit 中中断.


对更新的回应:

看看 NUnit 3 的Breaking Changes 页面。NUnit 2 和 3 之间有两个相关的重大变化。

  1. TestCaseSource 现在必须是静态的。
  2. CurrentDirectory 默认不再设置为 Environment.CurrentDirectory。

第一个你已经很容易解决了。第二,是什么现在导致你的问题。

NUnit 3 按以下顺序运行它的方法:

  1. 评估 TestCaseSource 方法 (OrdersTests.cs)
  2. 运行 SetUpFixture (Initialize.cs)
  3. 运行测试(ConfigTests/OrdersTests)

我不确定在您的 TestCaseSource 方法之前调用了什么 Config.cs - 您确定该顺序吗?做任何CreateSymbolTestCaseData()事情Config.cs你可以尝试重写你的 TestCaseSource :

private TestCaseData[] CreateSymbolTestCaseData()
{
    Environment.CurrentDirectory = "c:\RequiredDirectory";
    return new []
    {
        new TestCaseData("SPY", new Symbol(Security.GenerateEquity("SPY"), "SPY")),
        new TestCaseData("EURUSD", new Symbol(Security.GenerateForex("EURUSD"), "EURUSD"))
    };
}
于 2017-08-25T12:16:58.430 回答