Migration problems when migrate from NUnit 2.X to NUnit 3.X

1.2k views Asked by At

I'm using NUnit 2.X library but want to use NUnit 3.X now. I have some problems about migration from 2.X to 3.X. First i have a setup fixture class. Here is the 2.X version;

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();
        }
    }
}

First problem is fixed via change "Setup" attribute with "OneTimeSetUp" attribute. Second problem fixed via add some codes for set test directory. Because i'm using Re-Sharper test engine. Here is final shape of setup fixture;

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;
            }
        }
    }
}

Well after solve setup fixture problem, my real problems begins with use TestCaseSource/TestCaseData. Here is sample 2.X version;

[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 version creating exception and my tests are fail. Shortly exception telling that TestCaseData provider method must be static. Well, after mark method with static identifier test working correctly but this time my other test failing (before use static identifier it's not failing). Why my other test failing? Because it's reading a file from test directory and somehow test working before setup up fixture codes run and change test directory!

Before use static identifier first SetUpFixture codes run and then tests code run. After use static identifier order changing my test that read file from test directory (which is Re-Sharper's temporary directory and not contain necessary file) run first after that SetUpFixture codes run. Any idea how all my tests to be successful?

UPDATE:

Explain some units;

  1. I have Initialize.cs (part of my test assembly) which is responsible setup CurrentDirectory.
  2. I have Config.cs (part of my project infrastructure assembly) which is my project configuration file and it has public static readonly Setttings property which is reading configuration file from CurrentDirectory.
  3. I have ConfigTests.cs (part of my test assembly) which is contain some test methods for read/write Settings property.

When i debug tests;

  1. Before use any static TestCaseSource, they are working below order;

A. Initialize.cs => Setup method

B. Config.cs => static Settings property getter method

C. ConfigTests.cs => first test method

So initialize working first others working later all tests successfully passing from test.

  1. After use static TestCaseSource for inside other test file lets say OrdersTests.cs (excluded from project for first scenario after that included again), somehow working order is changing like below;

A. Config.cs => static Settings property getter method

B. OrdersTests.cs => static TestCaseSource method (not test method)

C. Initialize.cs => Setup method

D. ConfigTests.cs => first test method

E. OrdersTests.cs => first test method

So, my ConfigTests.cs tests failing because Initialize.cs working after Config.cs. I hope with this update my problem is more clear.

Is this problem related NUnit or Resharper or V.Studio? I don't know and all i know is my successfully passing tests are failing now!

UPDATE 2:

Chris,

Yes you are right. I explore project in detail and i saw the problem is related that my project's some classes accessing to static Config class and it's static Settings property (before run test setup fixture method and even before static test case source method!). You talk about order of process of test methods; NUnit doing tests like your said, not like i said. But when i try to use your solution (set current directory before test case source) it's not working. Because of that i solve my problem in another way. I'm not happy but at least my test methods working now. Could you please tell me what are the technical reasons that run static test case methods before initialize/setup method? Is this because of NUnit or because of infrastructure of .Net Framework? I'm not fanatic about NUnit and/or TDD. I don't have deep knowledge about these concepts but it does not make sense to me: run any method before setup method.

Thanks for your interest.

1

There are 1 answers

11
Chris On

Because it's reading a file from test directory and somehow test working before setup up fixture codes run and change test directory!

How are you reading this file? You should use TestContext.CurrentContext.TestDirectory to get the test directory in NUnit 3, rather than relying on the location of the current directory. See the Breaking Changes page for details.

Edit: I also see you've tagged this ReSharper 7.1. You should be aware that this version of resharper does not support NUnit 3 - the first version that did is ReSharper 10. Your tests will appear to run correctly - however you may experience weird side effects, and this may break in any future version of NUnit.


Response to update:

Take a look at NUnit 3's Breaking Changes page. There are two relevant breaking changes between NUnit 2 and 3.

  1. TestCaseSource's must now be static.
  2. The CurrentDirectory is no longer set to Environment.CurrentDirectory by default.

The first you've solved easily enough. The second, is what's now causing you issues.

NUnit 3 runs it's methods in this order:

  1. Evalute TestCaseSource methods (OrdersTests.cs)
  2. Run SetUpFixture (Initialize.cs)
  3. Run Test (ConfigTests/OrdersTests)

I'm not sure what Config.cs is being called before your TestCaseSource method - are you sure of that order? Does anything in CreateSymbolTestCaseData() call anything in Config.cs You could try rewriting your TestCaseSource as such:

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"))
    };
}