private static bool RunTestMethod(ITestCommand testCommand, MethodInfo methodInfo, XunitTestClassCommand testClassCommand,
                                          TestStep parentTestStep)
        {
            List <XunitTestCommand> xunitTestCommands;

            try
            {
                xunitTestCommands = new List <XunitTestCommand>(XunitTestCommandFactory.Make(testClassCommand,
                                                                                             XunitReflector.Wrap(methodInfo)));
            }
            catch (Exception ex)
            {
                // Xunit can throw exceptions when making commands if the test is malformed.
                ITestContext testContext = testCommand.StartPrimaryChildStep(parentTestStep);
                testContext.LogWriter.Failures.WriteException(ex, "Internal Error");
                testContext.FinishStep(TestOutcome.Failed, null);
                return(false);
            }

            if (xunitTestCommands.Count == 0)
            {
                return(true);
            }

            if (xunitTestCommands.Count == 1)
            {
                return(RunTestCommands(testCommand, testClassCommand, xunitTestCommands, parentTestStep, true));
            }

            // Introduce a common primary test step for theories.
            ITestContext primaryTestContext = testCommand.StartPrimaryChildStep(parentTestStep);
            bool         result             = RunTestCommands(testCommand, testClassCommand, xunitTestCommands, primaryTestContext.TestStep, false);

            primaryTestContext.FinishStep(result ? TestOutcome.Passed : TestOutcome.Failed, null);
            return(result);
        }
        private static TestResult RunTestClassCommandAndFinishStep(ITestCommand testCommand, ITestContext testContext, XunitTestClassCommand testClassCommand)
        {
            try
            {
                bool passed = true;

                // Run ClassStart behavior, if applicable.
                testContext.LifecyclePhase = LifecyclePhases.SetUp;
                Exception ex = testClassCommand.ClassStart();

                // Run tests.
                if (ex == null)
                {
                    List <MethodInfo>   testMethods  = new List <MethodInfo>();
                    List <ITestCommand> testCommands = new List <ITestCommand>();

                    foreach (ITestCommand child in testCommand.Children)
                    {
                        XunitTest test = child.Test as XunitTest;

                        if (test != null)
                        {
                            testMethods.Add(test.MethodInfo.Target.Resolve(false));
                            testCommands.Add(child);
                        }
                    }

                    while (testMethods.Count != 0)
                    {
                        XunitMethodInfo[] xunitTestMethods = GenericCollectionUtils.ConvertAllToArray(
                            testMethods, x => XunitReflector.Wrap(x));

                        int          nextTestIndex      = testClassCommand.ChooseNextTest(xunitTestMethods);
                        ITestCommand nextTestCommand    = testCommands[nextTestIndex];
                        MethodInfo   nextTestMethodInfo = testMethods[nextTestIndex];

                        testMethods.RemoveAt(nextTestIndex);
                        testCommands.RemoveAt(nextTestIndex);

                        passed &= RunTestMethod(nextTestCommand, nextTestMethodInfo, testClassCommand,
                                                testContext.TestStep);
                    }
                }

                // Run ClassFinish behavior, if applicable.
                testContext.LifecyclePhase = LifecyclePhases.TearDown;
                ex = testClassCommand.ClassFinish() ?? ex;

                if (ex != null)
                {
                    testContext.LogWriter.Failures.WriteException(ex, "Internal Error");
                    passed = false;
                }

                return(testContext.FinishStep(passed ? TestOutcome.Passed : TestOutcome.Failed, null));
            }
            catch (Exception ex)
            {
                // Xunit probably shouldn't throw an exception in a test command.
                // But just in case...
                testContext.LogWriter.Failures.WriteException(ex, "Internal Error");
                return(testContext.FinishStep(TestOutcome.Failed, null));
            }
        }