Running a console app programmatically (within a test)

This is a follow up to a comment on my recent post Debugging Child Processes in Visual Studio

I created a couple of helpful methods to run my console app within my acceptance test. This allows me to run the console app and see the output from it all from within my test runner.

private void RunConsoleApp(string filename, string arguments, int timeout = 60000)
{
    using (var process = new Process())
    {
        process.StartInfo.FileName = filename;
        process.StartInfo.Arguments = arguments;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;

        var output = new StringBuilder();
        var error = new StringBuilder();

        using (var outputWaitHandle = new AutoResetEvent(false))
        using (var errorWaitHandle = new AutoResetEvent(false))
        {
            process.OutputDataReceived += (sender, e) =>
            {
                if (e.Data == null)
                {
                    outputWaitHandle.Set();
                }
                else
                {
                    output.AppendLine(e.Data);
                }
            };
            process.ErrorDataReceived += (sender, e) =>
            {
                if (e.Data == null)
                {
                    errorWaitHandle.Set();
                }
                else
                {
                    error.AppendLine(e.Data);
                }
            };

            process.Start();

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();

            if (process.WaitForExit(timeout) &&
                outputWaitHandle.WaitOne(timeout) &&
                errorWaitHandle.WaitOne(timeout))
            {
                // Process completed. Check process.ExitCode here.
            }
            else
            {
                throw new Exception("Process timed out.");
                // Timed out.
            }
        }
        DumpString(output.ToString(), "Standard Output");
        DumpString(error.ToString(), "Standard Error");
    }
}

private static void DumpString(string content, string name)
{
    if (string.IsNullOrWhiteSpace(content)) return;

    Console.WriteLine();
    Console.WriteLine(name);
    Console.WriteLine(new string('+', 40));
    Console.WriteLine(content);
    Console.WriteLine(new string('-', 40));
    Console.WriteLine();
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s