Visual Studio 2015 测试运行程序中的“句柄无效”异常
Posted
技术标签:
【中文标题】Visual Studio 2015 测试运行程序中的“句柄无效”异常【英文标题】:"The handle is invalid" exception in Visual Studio 2015 test runner 【发布时间】:2015-10-19 23:27:29 【问题描述】:我发现我在 VS2013 中通过的一个测试在 VS2015 中失败了,该测试调用了一个服务,其中包括对 Console.Clear();
的调用
为了了解发生了什么,我做了一个简单的单元测试
[TestMethod]
public void ExampleTest()
Console.Clear();
此测试在 Visual Studio 2013 中通过,但在 2015 年出现以下错误:
测试名称:ExampleTest 测试全名:solution.Common.Test.CacheManagerTest.ExampleTest 测试源:C:\solution.Common.Test\CacheManagerTest.cs:第 34 行 测试结果:失败 测试时间:0:00:00.3015003
结果 StackTrace:在 System.IO.__Error.WinIOError(Int32 errorCode, System.Console.GetBufferInfo(Boolean) 处的字符串可能全路径 throwOnNoConsole, Boolean& 成功)在 System.Console.Clear() 在 sol.Common.Test.CacheManagerTest.ExampleTest() 中 C:\solution.Common.Test\CacheManagerTest.cs:第 35 行结果消息: 测试方法 Alexandria.Common.Test.CacheManagerTest.ExampleTest 抛出 异常:System.IO.IOException:句柄无效。
我明白,如果我的服务没有被控制台调用,它会失败是一种糟糕的设计。我问这个问题的原因是为了理解为什么在新版本中失败了的 Visual Studio。这是预期的行为吗?发生了什么变化?
我在更改日志中没有看到任何与此相关的明显内容。
编辑:我从以下 dll 调用 Console.clear
Microsoft\Framework.NETFramework\v4.5.1\mscorlib.dll
编辑 2:
两个视觉工作室中的 testproject 属性图片
【问题讨论】:
不。对我来说,这在 Visual Studio 2010 上失败了。您能否再次检查 VS2013 右键单击您的项目,选择属性 -> 选择应用程序选项卡 -> 检查输出类型。是说类库吗? @gideon 是的,它是一个类库 i.imgur.com/1Vedgyd.png 我正在使用 Microsoft Visual Studio Professional 2013 版本 12.0.31101.00 更新 4 哇,这很奇怪。它应该会中断,因为当它是类库时没有可用的控制台。是否有效,并清除控制台? @mmilan 您在测试项目中使用什么“.net 框架”?在 '.net 4.5'console.clear()
使用 Console.GetBufferInfo()
而不是 Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
作为你的调用堆栈。
@gideon 我还没有找到一种方法来实际检查它是否确实清除了控制台。对我来说,在 Vs2013 中通过测试是没有意义的,但确实如此。
【参考方案1】:
VS2015 中的变化非常明显,使用测试 > 调试 > 所有测试来获得洞察力。可以看到它现在有了一个新的测试宿主进程,它的名字是TE.ProcessHost.Managed.exe
,存放在C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow目录下。
以前版本的 VS 使用不同的主机 vstest.executionengine.exe。新测试主机的一个显着变化是它不再是控制台模式程序。通过在 exe 上运行 Dumpbin.exe /headers 可以看到一些内容。
查看潜在问题的另一种方法是使用任务管理器。请注意在较旧的 VS 版本中运行测试如何导致添加 conhost.exe
进程。这是拥有控制台模式应用程序的控制台窗口的进程。我之前看到的一个问题是这个过程往往会泄漏,而不是在测试完成时终止。添加更多的 conhost.exe 实例,在研究这个问题时,我运行了 12 个实例。据推测,VS2015 中的更改旨在解决该问题。
从技术上讲,您可以使用a .runsettings file 配置单元测试,并使用<ForcedLegacyMode>
元素强制使用旧的测试主机进程。然而,这对该测试的结果没有影响,看起来他们以多种方式解决了这个问题。
这是相当多的猜测,我建议您使用 connect.microsoft.com 提交反馈报告。您可以引用此 Q+A 以供参考。
同时,您可以考虑一种解决方法。请注意Console.Clear()
通常是一个麻烦制造者,当控制台模式应用程序的输出被重定向时,它也会在正常使用中失败。使用>
操作符在命令行提示符下很容易做到。这是它在单元测试中失败的最终原因。您需要使代码具有弹性,以便它可以在生产和单元测试中正常工作。像这样:
if (!Console.IsOutputRedirected) Console.Clear();
这需要针对 .NET 4.5 或更高版本。如果您需要针对早期版本,可以使用this SO post 中的代码。
【讨论】:
以上是关于Visual Studio 2015 测试运行程序中的“句柄无效”异常的主要内容,如果未能解决你的问题,请参考以下文章
MSTest Visual Studio 2015:未找到测试容器直接或间接引用的程序集或模块“xxxxxxx”
Visual Studio 2015 MSTest 无法运行负载测试