How to get Directory while running unit test

C#Unit TestingDirectory

C# Problem Overview


Hi when running my unit test I'm wanting to get the directory my project is running in to retrieve a file.

Say I have a Test project named MyProject. Test I run:

AppDomain.CurrentDomain.SetupInformation.ApplicationBase

and I receive "C:\\Source\\MyProject.Test\\bin\\Debug".

This is close to what I'm after. I don't want the bin\\Debug part.

Anyone know how instead I could get "C:\\Source\\MyProject.Test\\"?

C# Solutions


Solution 1 - C#

I would do it differently.

I suggest making that file part of the solution/project. Then right-click -> Properties -> Copy To Output = Copy Always.

That file will then be copied to whatever your output directory is (e.g. C:\Source\MyProject.Test\bin\Debug).

Edit: Copy To Output = Copy if Newer is the better option

Solution 2 - C#

Usually you retrieve your solution directory (or project directory, depending on your solution structure) like this:

string solution_dir = Path.GetDirectoryName( Path.GetDirectoryName(
    TestContext.CurrentContext.TestDirectory ) );

This will give you the parent directory of the "TestResults" folder created by testing projects.

Solution 3 - C#

Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

This will give you the directory you need....

as

AppDomain.CurrentDomain.SetupInformation.ApplicationBase 

gives nothing but

Directory.GetCurrentDirectory().

Have alook at this link

> http://msdn.microsoft.com/en-us/library/system.appdomain.currentdomain.aspx

Solution 4 - C#

Further to @abhilash's comment.

This works in my EXE's, DLL's and when tested from a different UnitTest project in both Debug or Release modes:

var dirName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.Replace("bin\\Debug", string.Empty));


        

Solution 5 - C#

/// <summary>
/// Testing various directory sources in a Unit Test project
/// </summary>
/// <remarks>
/// I want to mimic the web app's App_Data folder in a Unit Test project:
/// A) Using Copy to Output Directory on each data file
/// D) Without having to set Copy to Output Directory on each data file
/// </remarks>
[TestMethod]
public void UT_PathsExist()
{
    // Gets bin\Release or bin\Debug depending on mode
    string baseA = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
    Console.WriteLine(string.Format("Dir A:{0}", baseA));
    Assert.IsTrue(System.IO.Directory.Exists(baseA));

    // Gets bin\Release or bin\Debug depending on mode
    string baseB = AppDomain.CurrentDomain.BaseDirectory;
    Console.WriteLine(string.Format("Dir B:{0}", baseB));
    Assert.IsTrue(System.IO.Directory.Exists(baseB));

    // Returns empty string (or exception if you use .ToString()
    string baseC = (string)AppDomain.CurrentDomain.GetData("DataDirectory");
    Console.WriteLine(string.Format("Dir C:{0}", baseC));
    Assert.IsFalse(System.IO.Directory.Exists(baseC));


    // Move up two levels
    string baseD = System.IO.Directory.GetParent(baseA).Parent.FullName;
    Console.WriteLine(string.Format("Dir D:{0}", baseD));
    Assert.IsTrue(System.IO.Directory.Exists(baseD));


    // You need to set the Copy to Output Directory on each data file
    var appPathA = System.IO.Path.Combine(baseA, "App_Data");
    Console.WriteLine(string.Format("Dir A/App_Data:{0}", appPathA));
    // C:/solution/UnitTestProject/bin/Debug/App_Data
    Assert.IsTrue(System.IO.Directory.Exists(appPathA));

    // You can work with data files in the project directory's App_Data folder (or any other test data folder) 
    var appPathD = System.IO.Path.Combine(baseD, "App_Data");
    Console.WriteLine(string.Format("Dir D/App_Data:{0}", appPathD));
    // C:/solution/UnitTestProject/App_Data
    Assert.IsTrue(System.IO.Directory.Exists(appPathD));
}

Solution 6 - C#

I normally do it like that, and then I just add "..\..\" to the path to get up to the directory I want.

So what you could do is this:

var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"..\..\";

Solution 7 - C#

For NUnit this is what I do:

// Get the executing directory of the tests 
string dir = NUnit.Framework.TestContext.CurrentContext.TestDirectory;

// Infer the project directory from there...2 levels up (depending on project type - for asp.net omit the latter Parent for a single level up)
dir = System.IO.Directory.GetParent(dir).Parent.FullName;

If required you can from there navigate back down to other directories if required:

dir = Path.Combine(dir, "MySubDir");

Solution 8 - C#

The best solution I found was to put the file as an embedded resource on the test project and get it from my unit test. With this solution I don´t need to care about file paths.

Solution 9 - C#

I'm not sure if this helps, but this looks to be briefly touched on in the following question.

https://stackoverflow.com/questions/1041078/visual-studio-solution-path-environment-variable

Solution 10 - C#

In general you may use this, regardless if running a test or console app or web app:

// returns the absolute path of assembly, file://C:/.../MyAssembly.dll
var codeBase = Assembly.GetExecutingAssembly().CodeBase;    
// returns the absolute path of assembly, i.e: C:\...\MyAssembly.dll
var location = Assembly.GetExecutingAssembly().Location;

If you are running NUnit, then:

// return the absolute path of directory, i.e. C:\...\
var testDirectory = TestContext.CurrentContext.TestDirectory;

Solution 11 - C#

My approach relies on getting the location of the unit testing assembly and then traversing upwards. In the following snippet the variable folderProjectLevel will give you the path to the Unit test project.

string pathAssembly = System.Reflection.Assembly.GetExecutingAssembly().Location;
string folderAssembly = System.IO.Path.GetDirectoryName(pathAssembly);
if (folderAssembly.EndsWith("\\") == false) {
    folderAssembly = folderAssembly + "\\";
}
string folderProjectLevel = System.IO.Path.GetFullPath(folderAssembly + "..\\..\\");

Solution 12 - C#

According to https://github.com/nunit/nunit/issues/742#issuecomment-121964506

For NUnit3 , System.Environment.CurrentDirector is never changed, so it shall be the path of solution.

Eg:

string szProjectPath = System.Environment.CurrentDirectory + @"\where\your\project\is";

I prefer fixed location rather than GetParent(). One drawback of GetParent is when build is changed from AnyCPU to x86, default path would be changed from bin\Debug to bin\x86\Debug. Need to get another parent, and it's pain in the neck.

Also, you may still access to you test assemblies at TestContext.CurrentContext.TestDirectory and get output from TestContext.CurrentContext.WorkDirectory

Edit: Note: There are many changes in NUnit3. I will suggest reading through the documentation about "Breaking changes"

Solution 13 - C#

You can do it like this:

using System.IO;

Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, @"..\..\"));

Solution 14 - C#

use StackTrace

    internal static class Extensions
    {
        public static string GetSourceDirectoryName(this Type type)
        {
            StackTrace stackTrace = new StackTrace(true);

            foreach (var frame in stackTrace.GetFrames())
            {
                if (frame.GetMethod() is { } method && method.DeclaringType == type)
                {
                    return Path.GetDirectoryName(frame.GetFileName());
                }
            }

            throw new Exception($"未找到{type.Name}源文件目录");
        }
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnonyMouseView Question on Stackoverflow
Solution 1 - C#IlianView Answer on Stackoverflow
Solution 2 - C#Darien PardinasView Answer on Stackoverflow
Solution 3 - C#manu_dilip_shahView Answer on Stackoverflow
Solution 4 - C#Jeremy ThompsonView Answer on Stackoverflow
Solution 5 - C#user1207577View Answer on Stackoverflow
Solution 6 - C#AHMView Answer on Stackoverflow
Solution 7 - C#noelicusView Answer on Stackoverflow
Solution 8 - C#Andre L.A.C BittencourtView Answer on Stackoverflow
Solution 9 - C#David Z.View Answer on Stackoverflow
Solution 10 - C#houssView Answer on Stackoverflow
Solution 11 - C#Sau001View Answer on Stackoverflow
Solution 12 - C#Louis GoView Answer on Stackoverflow
Solution 13 - C#OgglasView Answer on Stackoverflow
Solution 14 - C#zlsView Answer on Stackoverflow