2

I would like to test a console app, redirecting the std out and std in as described here: Redirecting Console.Out within test Setup and Teardown

This is the code:

private StringWriter _sw;
private StringReader _sr;
[SetUp]
public void SetUp()
{
    _sw = new StringWriter();
    Console.SetOut(_sw);
    _sr = new StringReader("100");
    Console.SetIn(_sr);
}

[TearDown]
public void TearDown()
{
    var standardOut = new StreamWriter(Console.OpenStandardOutput());
    standardOut.AutoFlush = true;
    Console.SetOut(standardOut);
    Console.SetIn(new StreamReader(Console.OpenStandardInput()));
 }

Within each test, I will run code the reads and writes to the console.

As can be seen in the code above, each test will begin with:

  _sw = new StringWriter();
  Console.SetOut(_sw);

If multiple tests are run in parallel, will these tests conflict with each other?

Isn't it possible that calling Console.SetOut from one test, may change the redirection midway through another test? Wouldn't this disrupt the tests?

Community
  • 1
  • 1
Daryn
  • 3,394
  • 5
  • 30
  • 41
  • 1
    The term "thread safe" isn't useful for this discussion. For example, the definition that a single `Console.WriteLine` call sends output to either the original stream or the new one, never both, is not particularly useful for parallel unit testing. For that you need a thread-local output stream. – Ben Voigt Mar 28 '15 at 00:25
  • Is it possible for you to provide an example of using a thread-local output stream? – Daryn Mar 28 '15 at 00:37
  • It's always frustrating to get a -1 without an explanation – Daryn Mar 28 '15 at 08:48
  • Though I'm not the downvoter, I think your question could be phrased more constructively. You're trying to do something: ask about that - don't ask whether some particular method is "wise". Here, you seem to want how to redirect console output when using parallel testing - if that's even possible. You can (and should) still include your reasoning so far in the question, but don't make that the core of your question. Interesting question by the way (and if I might ask - why do you want this?) – Eamon Nerbonne Mar 29 '15 at 11:32

2 Answers2

4

So roughly, to redirect the console on a per-thread basis requires little more than a wrapper class. You will need:

  1. A static field, marked [ThreadLocal], to keep track of the stream for the current test on each thread.
  2. A SetOut method, probably static, much like the global (static) Console.SetOut method, that allows each test to set the above field during test setup.
  3. An implementation of the stream virtual methods, that reads the thread-local field and forwards output to it.
  4. An instance of this wrapper, passed to Console.SetOut.
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
0

Like you are implying, the answer to your questions is that the tests will interfere with each other.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
Jocke
  • 2,189
  • 1
  • 16
  • 24