예제 #1
0
        public void Should_IgnoreMutants_WithoutCoveringTestsInfo_When_Tests_Have_Changed()
        {
            // Arrange
            var diffProvider = new Mock <IDiffProvider>(MockBehavior.Loose);

            var options = new StrykerOptions()
            {
                WithBaseline   = false,
                ProjectVersion = "version"
            };

            diffProvider.Setup(x => x.ScanDiff()).Returns(new DiffResult
            {
                ChangedSourceFiles = new List <string>(),
                ChangedTestFiles   = new List <string> {
                    "C:/testfile.cs"
                }
            });

            diffProvider.SetupGet(x => x.Tests).Returns(new TestSet());
            var target = new SinceMutantFilter(diffProvider.Object);

            var mutants = new List <Mutant>
            {
                new Mutant {
                    CoveringTests = TestsGuidList.NoTest()
                }
            };

            // Act
            var results = target.FilterMutants(mutants, new CsharpFileLeaf(), options);

            // Assert
            results.ShouldBeEmpty();
        }
예제 #2
0
        public TestRunResult(bool success, string message = null)
        {
            FailingTests = !success?TestsGuidList.EveryTest() : TestsGuidList.NoTest();

            RanTests      = TestsGuidList.EveryTest();
            ResultMessage = message;
            Duration      = TimeSpan.Zero;
        }
        public static IProjectComponent CreateProjectWith(bool duplicateMutant = false, int mutationScore = 60)
        {
            var tree         = CSharpSyntaxTree.ParseText("void M(){ int i = 0 + 8; }");
            var originalNode = tree.GetRoot().DescendantNodes().OfType <BinaryExpressionSyntax>().First();

            var mutation = new Mutation()
            {
                OriginalNode    = originalNode,
                ReplacementNode = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression, originalNode.Left, originalNode.Right),
                DisplayName     = "This name should display",
                Type            = Mutator.Arithmetic
            };

            var folder = new CsharpFolderComposite {
                FullPath = "/home/user/src/project/", RelativePath = ""
            };
            int mutantCount = 0;

            for (var i = 1; i <= 2; i++)
            {
                var addedFolder = new CsharpFolderComposite
                {
                    RelativePath = $"{i}",
                    FullPath     = $"/home/user/src/project/{i}",
                };
                folder.Add(addedFolder);

                for (var y = 0; y <= 4; y++)
                {
                    var m = new Collection <Mutant>();
                    addedFolder.Add(new CsharpFileLeaf()
                    {
                        RelativePath = $"{i}/SomeFile{y}.cs",
                        FullPath     = $"/home/user/src/project/{i}/SomeFile{y}.cs",
                        Mutants      = m,
                        SourceCode   = "void M(){ int i = 0 + 8; }"
                    });

                    for (var z = 0; z <= 5; z++)
                    {
                        m.Add(new Mutant()
                        {
                            Id            = duplicateMutant ? 2 : ++mutantCount,
                            ResultStatus  = 100 / 6 * z < mutationScore ? MutantStatus.Killed : MutantStatus.Survived,
                            Mutation      = mutation,
                            CoveringTests = TestsGuidList.EveryTest()
                        });
                    }
                }
            }

            return(folder);
        }
예제 #4
0
        public void FilterMutants_FiltersNoMutants_IfTestsChanged()
        {
            // Arrange
            var diffProvider = new Mock <IDiffProvider>(MockBehavior.Loose);

            var options = new StrykerOptions()
            {
                WithBaseline   = false,
                ProjectVersion = "version"
            };

            diffProvider.Setup(x => x.ScanDiff()).Returns(new DiffResult
            {
                ChangedSourceFiles = new List <string>(),
                ChangedTestFiles   = new List <string> {
                    "C:/testfile1.cs"
                }
            });

            var tests = new TestSet();
            var test1 = new TestDescription(Guid.NewGuid(), "name1", "C:/testfile1.cs");
            var test2 = new TestDescription(Guid.NewGuid(), "name2", "C:/testfile2.cs");

            tests.RegisterTests(new[] { test1, test2 });
            diffProvider.SetupGet(x => x.Tests).Returns(tests);
            var target    = new SinceMutantFilter(diffProvider.Object);
            var testFile1 = new TestsGuidList(new [] { test1 });
            var testFile2 = new TestsGuidList(new [] { test2 });

            var expectedToStay1 = new Mutant {
                CoveringTests = testFile1
            };
            var expectedToStay2 = new Mutant {
                CoveringTests = testFile1
            };
            var newMutant = new Mutant {
                CoveringTests = testFile2
            };
            var mutants = new List <Mutant>
            {
                expectedToStay1,
                expectedToStay2,
                newMutant
            };

            // Act
            var results = target.FilterMutants(mutants, new CsharpFileLeaf(), options);

            // Assert
            results.ShouldBe(new [] { expectedToStay1, expectedToStay2 });
        }
        public void InitialTestProcess_ShouldThrowExceptionOnFail()
        {
            var testRunnerMock = new Mock <ITestRunner>(MockBehavior.Strict);
            var failedTest     = Guid.NewGuid();
            var successfulTest = Guid.NewGuid();
            var ranTests       = new TestsGuidList(failedTest, successfulTest);
            var failedTests    = new TestsGuidList(failedTest);

            testRunnerMock.Setup(x => x.InitialTest()).Returns(new TestRunResult(ranTests, failedTests, TestsGuidList.NoTest(), string.Empty, TimeSpan.Zero));
            testRunnerMock.Setup(x => x.CaptureCoverage(It.IsAny <List <Mutant> >()))
            .Returns(new TestRunResult(true));
            testRunnerMock.Setup(x => x.DiscoverTests()).Returns(new TestSet());

            Assert.Throws <InputException>(() => _target.InitialTest(_options, testRunnerMock.Object));
        }
예제 #6
0
        public void MutationTestExecutor_FailedTestShouldBeKilled()
        {
            var testRunnerMock = new Mock <ITestRunner>(MockBehavior.Strict);
            var mutant         = new Mutant {
                Id = 1, CoveringTests = TestsGuidList.EveryTest()
            };

            testRunnerMock.Setup(x => x.TestMultipleMutants(null, It.IsAny <IReadOnlyList <Mutant> >(), null)).Returns(new TestRunResult(false));

            var target = new MutationTestExecutor(testRunnerMock.Object);

            target.Test(new List <Mutant> {
                mutant
            }, null, null);

            mutant.ResultStatus.ShouldBe(MutantStatus.Killed);
            testRunnerMock.Verify(x => x.TestMultipleMutants(null, It.IsAny <IReadOnlyList <Mutant> >(), null), Times.Once);
        }
        private void TestMutants(IEnumerable <Mutant> mutantsToTest)
        {
            var mutantGroups = BuildMutantGroupsForTest(mutantsToTest.ToList());

            var parallelOptions = new ParallelOptions {
                MaxDegreeOfParallelism = _options.Concurrency
            };

            var testsFailingInitialy = Input.InitialTestRun.Result.FailingTests.GetGuids().ToHashSet();

            Parallel.ForEach(mutantGroups, parallelOptions, mutants =>
            {
                var reportedMutants = new HashSet <Mutant>();

                bool testUpdateHandler(IReadOnlyList <Mutant> testedMutants, ITestGuids failedTests, ITestGuids ranTests, ITestGuids timedOutTest)
                {
                    var continueTestRun = _options.OptimizationMode.HasFlag(OptimizationModes.DisableBail);
                    if (testsFailingInitialy.Count > 0 && failedTests.GetGuids().Any(id => testsFailingInitialy.Contains(id)))
                    {
                        // some of the failing tests where failing without any mutation
                        // we discard those tests
                        failedTests = new TestsGuidList(
                            failedTests.GetGuids().Where(t => !testsFailingInitialy.Contains(t)));
                    }
                    foreach (var mutant in testedMutants)
                    {
                        mutant.AnalyzeTestRun(failedTests, ranTests, timedOutTest);

                        if (mutant.ResultStatus == MutantStatus.NotRun)
                        {
                            continueTestRun = true; // Not all mutants in this group were tested so we continue
                        }

                        OnMutantTested(mutant, reportedMutants); // Report on mutant that has been tested
                    }

                    return(continueTestRun);
                }
                _mutationTestExecutor.Test(mutants, Input.InitialTestRun.TimeoutValueCalculator, testUpdateHandler);

                OnMutantsTested(mutants, reportedMutants);
            });
        }
예제 #8
0
 public TestRunResult CaptureCoverage(IEnumerable <Mutant> mutants)
 {
     _logger.LogDebug($"{RunnerId}: Capturing coverage.");
     if (CantUseStrykerDataCollector())
     {
         _logger.LogDebug($"{RunnerId}: project does not support StrykerDataCollector. Coverage data is simulated. Upgrade test proj" +
                          $" to@                                                                                                                  NetCore 2.0+");
         // can't capture coverage info
         foreach (var mutant in mutants)
         {
             mutant.CoveringTests = TestsGuidList.EveryTest();
         }
     }
     else
     {
         var testResults = RunTestSession(null, true, GenerateRunSettings(null, false, true, null));
         ParseResultsForCoverage(testResults.TestResults, mutants);
     }
     return(new TestRunResult(true));
 }
        public void InitialTestProcess_ShouldNotThrowIfAFewTestsFail()
        {
            var testRunnerMock = new Mock <ITestRunner>(MockBehavior.Strict);
            var test1          = Guid.NewGuid();
            var testList       = new List <Guid>(10);

            testList.Add(test1);
            for (int i = testList.Count; i < testList.Capacity; i++)
            {
                testList.Add(Guid.NewGuid());
            }
            var ranTests    = new TestsGuidList(testList);
            var failedTests = new TestsGuidList(test1);

            testRunnerMock.Setup(x => x.InitialTest()).Returns(new TestRunResult(ranTests, failedTests, TestsGuidList.NoTest(), string.Empty, TimeSpan.Zero));
            testRunnerMock.Setup(x => x.CaptureCoverage(It.IsAny <List <Mutant> >()))
            .Returns(new TestRunResult(true));
            testRunnerMock.Setup(x => x.DiscoverTests()).Returns(new TestSet());

            _target.InitialTest(_options, testRunnerMock.Object);
        }
예제 #10
0
        public void MutationTestExecutor_TimeoutShouldBePassedToProcessTimeout()
        {
            var testRunnerMock = new Mock <ITestRunner>(MockBehavior.Strict);
            var mutant         = new Mutant {
                Id = 1, CoveringTests = TestsGuidList.EveryTest()
            };

            testRunnerMock.Setup(x => x.TestMultipleMutants(It.IsAny <ITimeoutValueCalculator>(), It.IsAny <IReadOnlyList <Mutant> >(), null)).
            Returns(TestRunResult.TimedOut(TestsGuidList.NoTest(), TestsGuidList.NoTest(), TestsGuidList.EveryTest(), "", TimeSpan.Zero));

            var target = new MutationTestExecutor(testRunnerMock.Object);

            var timeoutValueCalculator = new TimeoutValueCalculator(500);

            target.Test(new List <Mutant> {
                mutant
            }, timeoutValueCalculator, null);

            mutant.ResultStatus.ShouldBe(MutantStatus.Timeout);
            testRunnerMock.Verify(x => x.TestMultipleMutants(timeoutValueCalculator, It.IsAny <IReadOnlyList <Mutant> >(), null), Times.Once);
        }
예제 #11
0
 private void SetCoveringTests(IReadOnlyCollection <Mutant> mutantsToScan)
 {
     // force static mutants to be tested against all tests.
     if (!_options.OptimizationMode.HasFlag(OptimizationModes.CaptureCoveragePerTest))
     {
         foreach (var mutant in mutantsToScan.Where(mutant => mutant.IsStaticValue))
         {
             mutant.CoveringTests = TestsGuidList.EveryTest();
         }
     }
     foreach (var mutant in mutantsToScan)
     {
         if (mutant.CoveringTests.IsEmpty)
         {
             mutant.ResultStatus       = MutantStatus.NoCoverage;
             mutant.ResultStatusReason = "Mutant has no test coverage";
         }
         else if (!_options.OptimizationMode.HasFlag(OptimizationModes.CoverageBasedTest))
         {
             mutant.CoveringTests = TestsGuidList.EveryTest();
         }
     }
 }
예제 #12
0
        private TestRunResult BuildTestRunResult(IRunResults testResults, int expectedTests, bool compressAll = true)
        {
            var resultAsArray = testResults.TestResults.ToArray();
            var testCases     = resultAsArray.Select(t => t.TestCase.Id).Distinct();
            var ranTestsCount = testCases.Count();
            var timeout       = !_aborted && ranTestsCount < expectedTests;
            var ranTests      = (compressAll && ranTestsCount >= DiscoverTests().Count) ? (ITestGuids)TestsGuidList.EveryTest() : new WrappedGuidsEnumeration(testCases);
            var failedTests   = resultAsArray.Where(tr => tr.Outcome == TestOutcome.Failed).Select(t => t.TestCase.Id);

            if (ranTests.IsEmpty && (testResults.TestsInTimeout == null || testResults.TestsInTimeout.Count == 0))
            {
                _logger.LogTrace($"{RunnerId}: Initial Test session reports 0 result and 0 stuck tests.");
            }

            var duration = testResults.TestResults.Aggregate(new TimeSpan(), (span, result) => span.Add(result.Duration));

            var message = string.Join(Environment.NewLine,
                                      resultAsArray.Where(tr => !string.IsNullOrWhiteSpace(tr.ErrorMessage))
                                      .Select(tr => $"{tr.DisplayName}{Environment.NewLine}{Environment.NewLine}{tr.ErrorMessage}"));
            var failedTestsDescription = new WrappedGuidsEnumeration(failedTests);
            var timedOutTests          = new WrappedGuidsEnumeration(testResults.TestsInTimeout?.Select(t => t.Id));

            return(timeout
                ? TestRunResult.TimedOut(ranTests, failedTestsDescription, timedOutTests, message, duration)
                : new TestRunResult(ranTests, failedTestsDescription, timedOutTests, message, duration));
        }
예제 #13
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));
        }