private static void VerifyTestFramework(string testFrameworkName)
        {
            var testFramework = TestFramework.GetFramework(testFrameworkName);

            if (testFramework == null)
            {
                throw new InvalidOperationException($"Unknown test framework: {testFrameworkName}");
            }
        }
        public override GetTestStartInfoResponse GetTestStartInfo(string methodName, string testFrameworkName)
        {
            var testFramework = TestFramework.GetFramework(testFrameworkName);

            if (testFramework == null)
            {
                throw new InvalidOperationException($"Unknown test framework: {testFrameworkName}");
            }

            SendMessage(TestExecution_GetTestRunnerProcessStartInfo);

            var message = ReadMessage();

            var testStartInfo = message.DeserializePayload <TestStartInfo>();

            var arguments = testStartInfo.Arguments;

            var endIndex = arguments.IndexOf("--designtime");

            if (endIndex >= 0)
            {
                arguments = arguments.Substring(0, endIndex).TrimEnd();
            }

            if (!string.IsNullOrEmpty(methodName))
            {
                arguments = $"{arguments} {testFramework.MethodArgument} {methodName}";
            }

            return(new GetTestStartInfoResponse
            {
                Executable = testStartInfo.FileName,
                Argument = arguments,
                WorkingDirectory = WorkingDirectory
            });
        }
        public override RunTestResponse RunTest(string methodName, string testFrameworkName)
        {
            var testFramework = TestFramework.GetFramework(testFrameworkName);

            if (testFramework == null)
            {
                throw new InvalidOperationException($"Unknown test framework: {testFrameworkName}");
            }

            SendMessage(TestExecution_GetTestRunnerProcessStartInfo);

            var testStartInfoMessage = ReadMessage();

            var testStartInfo = testStartInfoMessage.DeserializePayload <TestStartInfo>();

            var fileName = testStartInfo.FileName;
            // We pass in the tests as a list. So trimming out the wait-command that expects the tests to be sent as a separate message.
            var startInfoArguments = testStartInfo.Arguments.Replace("--wait-command", "");
            var arguments          = $"{startInfoArguments} {testFramework.MethodArgument} {methodName}";

            var startInfo = new ProcessStartInfo(fileName, arguments)
            {
                WorkingDirectory       = WorkingDirectory,
                CreateNoWindow         = true,
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                RedirectStandardError  = true
            };

            var testProcess = Process.Start(startInfo);

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

            testProcess.OutputDataReceived += (_, e) =>
            {
                EmitTestMessage(TestMessageLevel.Informational, e.Data ?? string.Empty);
                output.AppendLine(e.Data);
            };

            testProcess.ErrorDataReceived += (_, e) =>
            {
                EmitTestMessage(TestMessageLevel.Error, e.Data ?? string.Empty);
                error.AppendLine(e.Data);
            };

            testProcess.BeginOutputReadLine();
            testProcess.BeginErrorReadLine();

            var testResults = new List <LegacyTestResult>();
            var done        = false;

            while (!done)
            {
                var message = ReadMessage();

                switch (message.MessageType)
                {
                case TestExecution_TestResult:
                    testResults.Add(message.DeserializePayload <LegacyTestResult>());
                    break;

                case MessageType.ExecutionComplete:
                    done = true;
                    break;
                }
            }

            if (!testProcess.HasExited)
            {
                if (!testProcess.WaitForExit(3000))
                {
                    testProcess.KillChildrenAndThis();
                }
            }

            var results = testResults.Select(testResult =>
                                             new DotNetTestResult
            {
                MethodName      = testResult.Test.FullyQualifiedName,
                Outcome         = testResult.Outcome.ToString().ToLowerInvariant(),
                ErrorMessage    = testResult.ErrorMessage,
                ErrorStackTrace = testResult.ErrorStackTrace
            });

            return(new RunTestResponse
            {
                Results = results.ToArray(),
                Pass = !testResults.Any(r => r.Outcome == LegacyTestOutcome.Failed)
            });
        }