如何在运行单元测试时获取目录
本文关键字:获取 单元测试 运行 | 更新日期: 2023-09-27 18:31:32
嗨,在运行我的单元测试时,我想获取我的项目正在运行的目录来检索文件。
假设我有一个名为 MyProject 的测试项目。测试我运行:
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
我收到"C:''Source''MyProject.Test''bin''Debug"
.
这与我所追求的很接近。我不想要bin''Debug
部分。
有谁知道我怎么能得到"C:''Source''MyProject.Test''"
?
我会以不同的方式做。
我建议使该文件成为解决方案/项目的一部分。然后右键单击 ->属性 ->复制到输出 = 始终复制。
然后,该文件将被复制到您的输出目录(例如 C:''Source''MyProject.Test''bin''Debug)。
编辑:复制到输出 = 复制,如果较新是更好的选择
通常,您可以像这样检索解决方案目录(或项目目录,具体取决于解决方案结构):
string solution_dir = Path.GetDirectoryName( Path.GetDirectoryName(
TestContext.CurrentContext.TestDirectory ) );
这将为您提供由测试项目创建的"测试结果"文件夹的父目录。
Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
这将为您提供所需的目录。
如
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
什么也没给,但
Directory.GetCurrentDirectory().
看看这个链接
http://msdn.microsoft.com/en-us/library/system.appdomain.currentdomain.aspx
进一步@abhilash的评论。
这适用于我的 EXE、DLL 以及从调试或发布模式下的不同 UnitTest 项目进行测试时:
var dirName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.Replace("bin''Debug", string.Empty));
/// <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));
}
我通常这样做,然后我只是将"..'..'"
添加到路径中以进入我想要的目录。
所以你可以做的是:
var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"..'..'";
对于 NUnit,这就是我所做的:
// 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;
如果需要,您可以根据需要从那里导航回其他目录:
dir = Path.Combine(dir, "MySubDir");
根据 https://github.com/nunit/nunit/issues/742#issuecomment-121964506
对于 NUnit3,System.Environment.CurrentDirector 永远不会改变,所以它应该是解决方案的路径。
例如:
string szProjectPath = System.Environment.CurrentDirectory + @"'where'your'project'is";
我更喜欢固定位置而不是GetParent()。GetParent 的一个缺点是,当构建从 AnyCPU 更改为 x86 时,默认路径将从 bin''Debug 更改为 bin''x86''Debug。需要找另一个父母,这是脖子上的疼痛。
此外,您仍然可以在TestContext.CurrentContext.TestDirectory
访问测试程序集并从TestContext.CurrentContext.WorkDirectory
获取输出
编辑:注意:NUnit3 中有许多更改。我建议通读有关"重大更改"的文档
我找到的最佳解决方案是将文件作为嵌入式资源放在测试项目中,并从我的单元测试中获取它。使用此解决方案,我无需关心文件路径。
我不确定这是否有帮助,但这似乎在以下问题中简要介绍。
Visual Studio Solution Path 环境变量
通常,无论运行测试、控制台应用还是 Web 应用,都可以使用它:
// 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;
我的方法依赖于获取单元测试程序集的位置,然后向上遍历。在下面的代码片段中,变量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 + "..''..''");
这样做:
using System.IO;
Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, @"..'..'"));
使用 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}源文件目录");
}
}