从NUnit 2.X迁移到NUnit 3.X

时间:2017-08-24 21:34:50

标签: nunit tdd resharper nunit-3.0 resharper-7.1

我使用的是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"属性。通过为set test目录添加一些代码来修复第二个问题。因为我正在使用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代码然后测试代码运行。使用静态标识符顺序更改我的测试后,从测试目录中读取文件(这是Re-Sharper的临时目录,不包含必要的文件),在运行SetUpFixture代码后首先运行。知道我的所有测试如何成功吗?

更新

解释一些单位;

  1. 我有Initialize.cs(我的测试程序集的一部分),负责设置CurrentDirectory。
  2. 我有Config.cs(我的项目基础架构程序集的一部分),它是我的项目配置文件,它有公共静态只读Setttings属性,它从CurrentDirectory读取配置文件。
  3. 我有ConfigTests.cs(我的测试程序集的一部分),它包含一些读/写设置属性的测试方法。
  4. 当我调试测试时;

    1. 在使用任何静态TestCaseSource之前,它们按顺序工作;
    2. 一个。 Initialize.cs =>设置方法

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

      ℃。 ConfigTests.cs =>第一种测试方法

      因此,初始化工作的第一个其他人稍后工作所有测试成功通过测试。

      1. 使用静态TestCaseSource后面的其他测试文件让我们说OrdersTests.cs(从项目中排除第一个场景后再包括),不知何故工作顺序如下变化;
      2. 一个。 Config.cs =>静态设置属性getter方法

        B中。 OrdersTests.cs => static TestCaseSource方法(不是测试方法)

        ℃。 Initialize.cs =>设置方法

        d。 ConfigTests.cs =>第一种测试方法

        电子。 OrdersTests.cs =>第一种测试方法

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

        此问题是否与NUnit或Resharper或V.Studio有关?我不知道,我所知道的是我成功通过测试现在都失败了!

        更新2:

        克里斯,

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

        感谢您的关注。

1 个答案:

答案 0 :(得分:2)

  

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

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

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

对更新的回应:

看一下NUnit 3' Breaking Changes page。 NUnit 2和3之间有两个相关的重大变化。

  1. TestCaseSource现在必须是静态的。
  2. 默认情况下,CurrentDirectory不再设置为Environment.CurrentDirectory。
  3. 第一个你很容易解决的问题。第二,现在正在给你带来问题。

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

    1. 评估TestCaseSource方法(OrdersTests.cs)
    2. 运行SetUpFixture(Initialize.cs)
    3. 运行测试(ConfigTests / OrdersTests)
    4. 我不确定在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"))
          };
      }