我有一个控制台应用程序。在发布环境中,它目前运行良好。在IDE调试环境中,我不希望控制台窗口关闭,所以我添加了这个函数,并在程序的最后调用它。
[Conditional("DEBUG")]
public static void DebugWaitAKey(string message = "Press any key")
{
Console.WriteLine(message);
Console.ReadKey();
}
当我调试程序时,它对我很有用。但是通过单元测试,它在退出之前仍然会等待一个键!
解决方法只是我的程序的单元测试发行版,或测试其他功能。但我确实希望能够识别当前会话正在进行单元测试,并在此函数中使用该标志。
答案 0 :(得分:4)
我相信this应该回答你的问题。我从那里上了一堂课,并根据你的情况进行了调整。
/// <summary>
/// Detects if we are running inside a unit test.
/// </summary>
public static class UnitTestDetector
{
static UnitTestDetector()
{
string testAssemblyName = "Microsoft.VisualStudio.QualityTools.UnitTestFramework";
UnitTestDetector.IsInUnitTest = AppDomain.CurrentDomain.GetAssemblies()
.Any(a => a.FullName.StartsWith(testAssemblyName));
}
public static bool IsInUnitTest { get; private set; }
}
然后我在你的方法中添加了一行,如果它正在运行测试,它将不会命中Console.ReadKey();
[Conditional("DEBUG")]
public static void DebugWaitAKey(string message = "Press any key")
{
Console.WriteLine(message);
if(!UnitTestDetector.IsInUnitTest)
Console.ReadKey();
}
注意:这将被视为黑客攻击,不会被视为最佳做法。
修改强> 我还在github上创建了一个示例项目来演示此代码。 https://github.com/jeffweiler8770/UnitTest
答案 1 :(得分:1)
不是查看程序是否在调试模式下编译,而是查看是否附加了调试器:
if (Debugger.IsAttached)
{
Console.WriteLine(message);
Console.ReadKey();
}
请注意,这只会检测您是从Visual Studio开始使用F5,而不是Ctrl-F5(即仅使用调试启动)
答案 2 :(得分:1)
如果您的测试从专用的UnitTest项目运行,那么这是一种简单的方法:在AppSettings中使用一个标志......
我不会为了这样的目的调查模式,我会在具有自己配置的专用UnitTest项目中运行测试。
如果您需要收集数据,可能只需使用跟踪(可以从.config文件中自定义)......?
希望这会有所帮助......
答案 3 :(得分:0)
我使用了Jeff的UnitTestDetector变体。我不想检查单元测试组件,并希望控制哪些单元测试会考虑这个。
所以我创建了一个简单的类,IsInUnitTest默认为false。 然后在我想要运行条件代码的单元测试类中,我添加了TestInitializer和TestCleanup,我相应地设置了bool。
然后在我的常规代码中,我可以使用UnitTestDetector.IsInUnitTest
Simple UnitTestDetector类:
/// <summary>
/// Detects if we are running inside a unit test.
/// </summary>
public static class UnitTestDetector
{
static private bool _isInUnitTest = false;
public static bool IsInUnitTest
{
get { return _isInUnitTest; }
set { _isInUnitTest = value; }
}
}
测试这个东西的单元测试:
[TestClass]
public class UnitTestDetectorTest_WithoutIsInUnitTest
{
[TestMethod]
public void IsInUnitTest_WithoutUnitTestAttribute_False()
{
bool expected = false;
bool actual = UnitTestDetector.IsInUnitTest;
Assert.AreEqual(expected, actual);
}
}
[TestClass]
public class UnitTestDetectorTest_WithIsInUnitTest
{
[TestInitialize()]
public void Initialize()
{
UnitTestDetector.IsInUnitTest = true;
}
[TestCleanup()]
public void Cleanup()
{
UnitTestDetector.IsInUnitTest = false;
}
[TestMethod]
public void IsInUnitTest_WithUnitTestAttribute_True()
{
bool expected = true;
bool actual = UnitTestDetector.IsInUnitTest;
Assert.AreEqual(expected, actual);
}
}
代码中的条件:
if (UnitTestDetector.IsInUnitTest)
return "Hey I'm in the unit test :)";
答案 4 :(得分:0)
我知道这很旧,但是我真的不喜欢其中的许多答案,尤其是那些硬编码程序集名称或版本的答案。
这很好,只要您要测试的课程是非密封即可。很简单:
将此类变量添加到要测试的类中:
protected Boolean IsInUnitTestMode = false;
我们默认将其设置为false,因此在生产中它将始终为false。
将类似这种包装的东西添加到测试类中
class ProfileTest : Profiles
{
public ProfileTest() : base()
{
IsInUnitTestMode = true;
}
}
在此示例中, Profiles 是我们正在测试的类, ProfileTest 是测试项目名称空间中的包装器类。它将永远不会被部署。测试类使用它来创建要测试的类的实例:
ProfileTest profiles = new ProfileTest();
与此相反:
private Profiles profiles = new Profiles();
我们可以这样使用它:
private string ProfilePath
{
get
{
if (IsInUnitTestMode)
return SafeStorage.EnsureFolderExists(Path.Combine(SafeStorage.UserPath, UNITTESTFOLDERNAME)).FullName;
else
return SafeStorage.EnsureFolderExists(Path.Combine(SafeStorage.UserPath, PROFILEFOLDERNAME)).FullName;
}
}
正如我所说,这不适用于密封类,也不适用于静态类。如此说来,我实际上选择测试单元测试条件的次数非常少。这对我来说非常好。