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

Comments

Projects
None yet
@starteleport
Copy link

commented Nov 26, 2015

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

This comment has been minimized.

Copy link
Member

commented Nov 26, 2015

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

This comment has been minimized.

Copy link

commented Feb 15, 2016

@imakowski

This comment has been minimized.

Copy link
Contributor

commented May 12, 2016

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Contributor

commented May 12, 2016

@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

This comment has been minimized.

Copy link
Member

commented May 12, 2016

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

Fix assembly resolution exception that would happen during every test
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

Fix assembly resolution exception that would happen during every test
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

Fix assembly resolution exception that would happen during every test
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 added a commit to mono/linker that referenced this issue May 2, 2017

Fix assembly resolution exception that would happen during every test
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 added a commit to marek-safar/linker that referenced this issue May 2, 2017

Fix assembly resolution exception that would happen during every test
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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Contributor

commented May 11, 2017

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

@shvez

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Contributor

commented May 11, 2017

I was wrong.

It is TestContext.CurrentContext.TestDirectory.

However, it is not there on the PORTABLE build.

@oznetmaster

This comment has been minimized.

Copy link
Contributor

commented May 11, 2017

#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

This comment has been minimized.

Copy link

commented May 11, 2017

it is there in 3.6.0 but not in 3.6.1

@oznetmaster

This comment has been minimized.

Copy link
Contributor

commented May 11, 2017

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

@oznetmaster

This comment has been minimized.

Copy link
Contributor

commented May 11, 2017

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

@shvez

This comment has been minimized.

Copy link

commented May 11, 2017

yes, i'm using it

@oznetmaster

This comment has been minimized.

Copy link
Contributor

commented May 11, 2017

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

This comment has been minimized.

Copy link

commented May 11, 2017

thank you

@mousavii

This comment has been minimized.

Copy link

commented Sep 22, 2017

Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

@SidShetye

This comment has been minimized.

Copy link

commented Dec 28, 2017

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

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

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

@abelbraaksma

This comment has been minimized.

Copy link

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
You can’t perform that action at this time.