如何在运行单元测试时获取目录

时间:2012-04-18 06:36:26

标签: c# unit-testing directory

嗨,在运行我的单元测试时,我想要运行我的项目所在的目录来检索文件。

假设我有一个名为MyProject的测试项目。测试我跑:

AppDomain.CurrentDomain.SetupInformation.ApplicationBase

我收到"C:\\Source\\MyProject.Test\\bin\\Debug"

这接近我所追求的目标。我不想要bin\\Debug部分。

任何人都知道如何获得"C:\\Source\\MyProject.Test\\"

14 个答案:

答案 0 :(得分:61)

我会采用不同的方式。

我建议将该文件作为解决方案/项目的一部分。然后右键单击 - >属性 - >复制到输出=始终复制。

然后将该文件复制到您的输出目录(例如C:\ Source \ MyProject.Test \ bin \ Debug)。

答案 1 :(得分:36)

通常您会检索解决方案目录(或项目目录,具体取决于您的解决方案结构),如下所示:

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

这将为您提供测试项目创建的“TestResults”文件夹的父目录。

答案 2 :(得分:23)

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

这将为您提供所需的目录....

作为

AppDomain.CurrentDomain.SetupInformation.ApplicationBase 

只提供

Directory.GetCurrentDirectory().

已经参与此链接

  

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

答案 3 :(得分:7)

继续@ abhilash的评论。

这适用于我的EXE,DLL的以及在调试或发布模式下从不同的UnitTest项目进行测试时:

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

答案 4 :(得分:6)

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

答案 5 :(得分:5)

我通常这样做,然后我只需在路径中添加"..\..\"即可到达我想要的目录。

所以你能做的就是:

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

答案 6 :(得分:1)

我不确定这是否有帮助,但在下面的问题中可以简要介绍一下这个问题。

Visual Studio Solution Path environment variable

答案 7 :(得分:1)

我找到的最佳解决方案是将文件作为嵌入式资源放在测试项目中,并从我的单元测试中获取。使用此解决方案,我不需要关心文件路径。

答案 8 :(得分:1)

对于NUnit,我就是这样做的:

<?xml version="1.0" encoding="UTF-8" ?>
<ruleset name="Complex PHP Mess Detector Rule Set"
    xmlns="http://pmd.sf.net/ruleset/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
    <rule ref="rulesets/naming.xml">
        <exclude name="LongVariable" />
        <exclude name="ShortMethodName" />
    </rule>
    <rule ref="rulesets/naming.xml/LongVariable">
        <properties>
            <property name="maximum" value="32" />
        </properties>
    </rule>
    <rule ref="rulesets/naming.xml/ShortMethodName">
        <properties>
            <property name="minimum" value="3" />
            <property name="exceptions" value="ln" />
        </properties>
    </rule>
    <rule ref="rulesets/design.xml/ExitExpression" />
    <rule ref="rulesets/design.xml/EvalExpression" />
    <rule ref="rulesets/design.xml/GotoStatement" />
    <rule ref="rulesets/design.xml/DepthOfInheritance" />
    <rule ref="rulesets/design.xml/CouplingBetweenObjects" />
    <rule ref="rulesets/design.xml/NumberOfChildren" />
    <rule ref="rulesets/unusedcode.xml" />
    <rule ref="rulesets/controversial.xml" />
</ruleset>

如果需要,您可以从那里导航回到其他目录(如果需要):

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

答案 9 :(得分:1)

一般情况下,无论是运行测试版还是控制台应用程序或网络应用程序,都可以使用此功能:

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

如果您正在运行NUnit,那么:

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

答案 10 :(得分:0)

你可以这样做:

using System.IO;

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

答案 11 :(得分:0)

我的方法依赖于获取单元测试组件的位置,然后向上遍历。在以下代码段中,变量folderProjectLevel将为您提供单元测试项目的路径。

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 + "..\\..\\");

答案 12 :(得分:0)

根据https://github.com/nunit/nunit/issues/742#issuecomment-121964506

对于NUnit3,永远不会更改System.Environment.CurrentDirector,因此它应该是解决方案的路径。

例如:

$url = "http://xxx.yyy.zzz/u/register.php?CID=815112955&f=472&p=2&a=r&SID=&el=&llid=&counted=&c=&optin=y&interest[]=[Interessen]&inp_3=".$email.'&inp_1005='.$utm_source;
  $result = shortenurl($url);

  function shortenurl($url)
    {
     if ( strlen($url) > 45) {
      return substr($url, 0, 30)."[...]".substr($url, -15);
     } else {
      return $url;
     }
  }

我更喜欢固定位置而不是GetParent()。 GetParent的一个缺点是,当构建从AnyCPU更改为x86时,默认路径将从bin \ Debug更改为bin \ x86 \ Debug。 需要再找一个父母,这在脖子上很痛苦。

此外,您仍然可以通过string szProjectPath = System.Environment.CurrentDirectory + @"\where\your\project\is"; 访问测试程序集。

编辑: 注意:NUnit3中有许多更改。我建议您通读有关"Breaking changes"

的文档

答案 13 :(得分:0)

使用堆栈跟踪

    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}源文件目录");
        }
    }