23

I found that one of my tests that passes in VS2013 is failing in VS2015, the test calls a service that includes among other things a call to Console.Clear();

to find out whats going on I made a simple unit test

   [TestMethod]
    public void ExampleTest()
    {
        Console.Clear();
    }

This test passes in visual studio 2013 but in 2015 I get the following error:

Test Name: ExampleTest Test FullName: solution.Common.Test.CacheManagerTest.ExampleTest Test Source: C:\solution.Common.Test\CacheManagerTest.cs : line 34 Test Outcome: Failed Test Duration: 0:00:00.3015003

Result StackTrace: at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded) at System.Console.Clear()
at sol.Common.Test.CacheManagerTest.ExampleTest() in C:\solution.Common.Test\CacheManagerTest.cs:line 35 Result Message:
Test method Alexandria.Common.Test.CacheManagerTest.ExampleTest threw exception: System.IO.IOException: The handle is invalid.

I do understand that it is bad design for my service to fail if it is not called by a console. The reason I am asking this question is to understand why this is failing in the new version of Visual Studio. Is this the intended behavior? What changed?

I did not see anything obvious in the change log that would seem related to this.

Edit: I am calling the Console.clear from the following dll

Microsoft\Framework.NETFramework\v4.5.1\mscorlib.dll

Edit 2:

picture of testproject properties in both visual studios both visual studios

mmilan
  • 1,738
  • 8
  • 31
  • 57
  • Nope. For me this fails on Visual Studio 2010. Can you double check in **VS2013** Right Click your project, Select Properties - > Select the Application Tab -> Check output type. Does it say class library? – gideon Jul 31 '15 at 06:54
  • @gideon yes it is a class library http://i.imgur.com/1Vedgyd.png I am using Microsoft Visual Studio Professional 2013 Version 12.0.31101.00 Update 4 – mmilan Jul 31 '15 at 07:15
  • Wow that's pretty weird. It should break, since the there isn't console available when it's a class library. Does it work, and clear the console ? – gideon Jul 31 '15 at 07:25
  • @mmilan What '.net framework' do you use in your test project? In '.net 4.5' `console.clear()` use `Console.GetBufferInfo()` instead of `Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)` as your callstack. – Old Fox Jul 31 '15 at 07:28
  • @gideon I haven't found a way to actually check if it does clear the console. To me it makes no sense for the test to pass in Vs2013 but it does. – mmilan Jul 31 '15 at 07:41
  • @mmilan yep. Very strange. Guess you'll could file a connect bug if you want to know more. – gideon Jul 31 '15 at 07:46
  • @OldFox I edited the question with a screenshot giving more information regarding the test project settings – mmilan Jul 31 '15 at 07:54
  • @mmilan My proj(its .net 4.5.1 same as yours...) in VS2013 use the `Microsoft.NET\Framework\v4.0.30319\mscorlib.dll` instead of `Microsoft\Framework.NETFramework\v4.5.1\mscorlib.dll`. So probably Microsoft did some refactoring to `Console` class. I'll install VS2015 and update. – Old Fox Jul 31 '15 at 08:15

1 Answers1

18

The changes in VS2015 are pretty visible, use the Test > Debug > All Tests to get insight. You can see that it now has a new test host process, its name is TE.ProcessHost.Managed.exe, stored in the C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow directory.

Previous versions of VS used a different host, vstest.executionengine.exe. One notable change in the new test host is that it is no longer a console mode program. Something you can see by running Dumpbin.exe /headers on the exe.

Another way to see the underlying problem is with Task Manager. Note how running a test in an older VS version causes a conhost.exe process to get added. This is the process that owns the console window for a console mode app. A problem I've seen before is that this process tends to leak, not terminating when the test completes. Adding ever more conhost.exe instances, at one point researching this problem I had 12 of them running. Presumably the changes in VS2015 were meant to address that problem.

Technically you can configure the unit test with a .runsettings file and use the <ForcedLegacyMode> element to force the old test host process to be used. This however has no effect on the outcome of this test, looks like they addressed this in multiple ways.

That's a fair amount of guessing, I recommend you use connect.microsoft.com to file a feedback report. You can quote this Q+A for reference.


Meanwhile, you can consider a workaround. Do note that Console.Clear() is in general a trouble-maker, it will also fail in normal usage when the output of a console mode app is redirected. Very easy to do from a command line prompt with the > operator. Which is the ultimate reason it fails in a unit test. You'll want to make the code resilient so it can work properly both in production and in a unit test. Like this:

    if (!Console.IsOutputRedirected) Console.Clear();

Which requires targeting .NET 4.5 or higher. You can use the code in this SO post if you need to target earlier versions.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536