Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working directory for tests in console NUnit 3 #1072

Closed
starteleport opened this issue Nov 26, 2015 · 21 comments
Closed

Working directory for tests in console NUnit 3 #1072

starteleport opened this issue Nov 26, 2015 · 21 comments

Comments

@starteleport
Copy link

In NUnit 2.6.4, working dir for my tests was set to corresponding bin/Debug directory of test DLL. This allowed me to load external files in tests by relative path.

It seems that now working dir is set to the working directory of console runner. Is this by design?

How can I leave test results (*.xml files) in work dir of console runner while having working dir for my tests set to bin/Debug?

@CharliePoole
Copy link
Contributor

This is by design, as shown here: https://github.com/nunit/nunit/wiki/Breaking-Changes

In earlier versions, NUnit changed the working directory. It no longer does so. You can use TestContext.TestDirectory to get the directory that contains the test assembly.

@tjrobinson
Copy link

New URL: https://github.com/nunit/docs/wiki/Breaking-Changes

@imakowski
Copy link
Contributor

This breaks a lot of test! Why you changed that? Some of the tests cannot be fixed because runtime code of tested app had dependency that working directory is location of test assembly.

@rprouse
Copy link
Member

rprouse commented May 12, 2016

@imakowski have you tried setting the current working directory to a known directory in an assembly setup? Untested code, but something like;

[SetUpFixture]
public class MySetUpClass
{
    [OneTimeSetUp]
    RunBeforeAnyTests()
    {
        var dir = Path.GetDirectoryName(typeof(MySetUpClass).Assembly.Location);
        Environment.CurrentDirectory = dir;

        // or
        Directory.SetCurrentDirectory(dir);
    }
}

@rprouse
Copy link
Member

rprouse commented May 12, 2016

@imakowski you may not have control over it, but code/applications should not rely on the current working directory being set. Applications should always determine their bin directory with code like I presented above. There are several API calls in Windows that change the current working directory without you being aware of it. Your application could run fine most of the time, but then fail after a user visits a seldom used part of of your application.

@NikolayPianikov
Copy link
Member

@rprouse this code is not working when is in the shadow copy mode
var dir = Path.GetDirectoryName(typeof(MySetUpClass).Assembly.Location);

You could use this in that case:
var dir = Path.GetDirectoryName(new Uri(typeof(MySetUpClass).Assembly.CodeBase).LocalPath);

@CharliePoole
Copy link
Contributor

Alternatively, we provide it for you as TestContext.CurrentContext.TestDirectory. :-)

We use the Uri as suggested with a few adjustments for special cases.

@rprouse rprouse modified the milestone: Closed Without Action Jan 10, 2017
mrvoorhe added a commit to Unity-Technologies/linker that referenced this issue May 1, 2017
The reason this issue started when the tests were moved upstream was due to a behavior change in the newer nunit.  nunit/nunit#1072

This PR uses more explicit resolution for the input & output which is more correct anyways
mrvoorhe added a commit to Unity-Technologies/linker that referenced this issue May 1, 2017
The reason this issue started when the tests were moved upstream was due to a behavior change in the newer nunit.  nunit/nunit#1072

This PR uses more explicit resolution for the input & output which is more correct anyways
mrvoorhe added a commit to Unity-Technologies/linker that referenced this issue May 1, 2017
The reason this issue started when the tests were moved upstream was due to a behavior change in the newer nunit.  nunit/nunit#1072

This PR uses more explicit resolution for the input & output which is more correct anyways
marek-safar pushed a commit to dotnet/linker that referenced this issue May 2, 2017
The reason this issue started when the tests were moved upstream was due to a behavior change in the newer nunit.  nunit/nunit#1072

This PR uses more explicit resolution for the input & output which is more correct anyways
marek-safar pushed a commit to marek-safar/linker that referenced this issue May 2, 2017
The reason this issue started when the tests were moved upstream was due to a behavior change in the newer nunit.  nunit/nunit#1072

This PR uses more explicit resolution for the input & output which is more correct anyways
@shvez
Copy link

shvez commented May 11, 2017

Alternatively, we provide it for you as TestContext.CurrentContext.TestDirectory. :-)

there is no TestDirectory property in CurrentContext anymore. i use nunit 3.6.1. there is only WorkDirectory which in my case when i start test from resharper points to wrong place :(

@oznetmaster
Copy link
Contributor

There is TestContext.TestDirectory. It is a static property. I believe that WorkDirectory is as well?

@shvez
Copy link

shvez commented May 11, 2017

well, i can not find it either using visual studio browser or compiler or teleric decompiler.
but i see it in nunit 3.5. not sure what is wrong

@oznetmaster
Copy link
Contributor

I was wrong.

It is TestContext.CurrentContext.TestDirectory.

However, it is not there on the PORTABLE build.

@oznetmaster
Copy link
Contributor

#if !PORTABLE
        /// <summary>
        /// Gets the directory containing the current test assembly.
        /// </summary>
        public string TestDirectory
        {
            get
            {
                Assembly assembly = _testExecutionContext?.CurrentTest?.TypeInfo?.Assembly;

                if (assembly != null)
                    return AssemblyHelper.GetDirectoryName(assembly);

#if NETSTANDARD1_6
                // Test is null, we may be loading tests rather than executing.
                // Assume that the NUnit framework is in the same directory as the tests
                return AssemblyHelper.GetDirectoryName(typeof(TestContext).GetTypeInfo().Assembly);
#else
                // Test is null, we may be loading tests rather than executing.
                // Assume that calling assembly is the test assembly.
                return AssemblyHelper.GetDirectoryName(Assembly.GetCallingAssembly());
#endif
            }
        }
#endif

@shvez
Copy link

shvez commented May 11, 2017

it is there in 3.6.0 but not in 3.6.1

@oznetmaster
Copy link
Contributor

I am looking at the current github repo, and it is exactly as I copied and pasted above.

@oznetmaster
Copy link
Contributor

Are you sure you are not using the PORTABLE build somehow?

@shvez
Copy link

shvez commented May 11, 2017

yes, i'm using it

@oznetmaster
Copy link
Contributor

Well, that is why it is not there. It is not supported in the PORTABLE build, and never has been, to my knowledge. However, I have never used the PORTABLE build, just run the CI tests against it.

@shvez
Copy link

shvez commented May 11, 2017

thank you

@mousavii
Copy link

Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

@SidShetye
Copy link

SidShetye commented Dec 28, 2017

For people eyeballing for actual code, putting together what @CharliePoole and @rprouse said, it's

[SetUpFixture]
public class MySetUpClass
{
    [OneTimeSetUp]
    public void RunBeforeAnyTests()
    {
        Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory;
        // or identically under the hoods
        Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
    }
}

For global initialization

Just don't enclose the above logic inside any namespace. i.e.

using NUnit.Framework;
using System;
using System.IO;

[SetUpFixture]
public class GlobalSetup
{
    [OneTimeSetUp]
    public void RunBeforeAnyTests()
    {
        Environment.CurrentDirectory = TestContext.CurrentContext.TestDirectory;
        // or identically under the hoods
        Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
    }
}

Also, seems the TestContext.CurrentContext.TestDirectory has some more intelligence to address corner cases, so I'd pick that over typeof(MySetUpClass).Assembly.Location

@abelbraaksma
Copy link

abelbraaksma commented May 27, 2018

so I'd pick that over typeof(MySetUpClass).Assembly.Location

Location returns the shadow location if the assembly is shadow-copied, typically you wouldn't want that. Use CodeBase instead, which returns a Uri of the actual location it is initially run from, prior to any shadow-copying.

Obviously it is better to use TestDirectory, but there seem to be issues with that property, see #2872, causing exceptions that cannot be caught. I don't know if they can also appear if you use OneTimeSetup (I assume not), but care should be taken until that is addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests