Beispiel #1
0
        public TestRunResult TestMultipleMutants(ITimeoutValueCalculator timeoutCalc, IReadOnlyList <Mutant> mutants, TestUpdateHandler update)
        {
            var mutantTestsMap = new Dictionary <int, ITestGuids>();
            var needAll        = true;
            ICollection <Guid> testCases;
            int?timeOutMs = timeoutCalc?.DefaultTimeout;

            if (mutants != null)
            {
                // if we optimize the number of tests to run
                if (_options.OptimizationMode.HasFlag(OptimizationModes.CoverageBasedTest))
                {
                    needAll = false;
                    foreach (var mutant in mutants)
                    {
                        ITestListDescription tests;
                        if ((mutant.IsStaticValue && !_options.OptimizationMode.HasFlag(OptimizationModes.CaptureCoveragePerTest)) || mutant.MustRunAgainstAllTests)
                        {
                            tests   = TestsGuidList.EveryTest();
                            needAll = true;
                        }
                        else
                        {
                            tests = mutant.CoveringTests;
                        }
                        mutantTestsMap.Add(mutant.Id, tests);
                    }

                    testCases = needAll ? null : mutants.SelectMany(m => m.CoveringTests.GetGuids()).ToList();

                    _logger.LogTrace($"{RunnerId}: Testing [{string.Join(',', mutants.Select(m => m.DisplayName))}] " +
                                     $"against {(testCases == null ? "all tests." : string.Join(", ", testCases))}.");
                    if (testCases?.Count == 0)
                    {
                        return(new TestRunResult(TestsGuidList.NoTest(), TestsGuidList.NoTest(), TestsGuidList.NoTest(), "Mutants are not covered by any test!", TimeSpan.Zero));
                    }

                    if (timeoutCalc != null && testCases != null)
                    {
                        // compute time out
                        var duration = (int)testCases.Select(id => _vsTests[id].InitialRunTime.TotalMilliseconds).Sum();
                        timeOutMs = timeoutCalc.CalculateTimeoutValue(duration);
                    }
                }
                else
                {
                    if (mutants.Count > 1)
                    {
                        throw new GeneralStrykerException("Internal error: trying to test multiple mutants simultaneously without 'perTest' coverage analysis.");
                    }
                    mutantTestsMap.Add(mutants[0].Id, TestsGuidList.EveryTest());
                    testCases = null;
                }
            }
            else
            {
                testCases = null;
            }

            var numberTestCases = testCases == null ? 0 : testCases.Count;
            var expectedTests   = needAll ? DiscoverTests().Count : numberTestCases;

            void HandleUpdate(IRunResults handler)
            {
                var handlerTestResults = handler.TestResults;

                if (mutants == null)
                {
                    return;
                }
                var tests = handlerTestResults.Count == DiscoverTests().Count
                    ? (ITestGuids)TestsGuidList.EveryTest()
                    : new WrappedGuidsEnumeration(handlerTestResults.Select(t => t.TestCase.Id));
                var failedTest = new WrappedGuidsEnumeration(handlerTestResults.Where(tr => tr.Outcome == TestOutcome.Failed)
                                                             .Select(t => t.TestCase.Id));
                var timedOutTest     = new WrappedGuidsEnumeration(handler.TestsInTimeout?.Select(t => t.Id));
                var remainingMutants = update?.Invoke(mutants, failedTest, tests, timedOutTest);

                if (handlerTestResults.Count >= expectedTests || remainingMutants != false || _aborted)
                {
                    return;
                }
                // all mutants status have been resolved, we can stop
                _logger.LogDebug($"{RunnerId}: Each mutant's fate has been established, we can stop.");
                _vsTestConsole.CancelTestRun();
                _aborted = true;
            }

            _logger.LogDebug("Using {0} ms as testrun timeout", timeOutMs.ToString() ?? "no");

            var testResults = RunTestSession(mutantTestsMap, needAll, GenerateRunSettings(timeOutMs, mutants != null, false, mutantTestsMap), HandleUpdate);

            return(BuildTestRunResult(testResults, expectedTests));
        }