public MutationTestRunner( ITestRunner testRunner, ICoverageAnalysisResult coverageAnalysisResult, IEventListener eventListener = null) { this.testRunner = testRunner; this.coverageAnalysisResult = coverageAnalysisResult; this.eventListener = eventListener ?? new NullEventListener(); }
public MutationJob( SyntaxNode originalSyntaxRoot, SyntaxNode originalNode, Document originalClass, string memberName, Config config, IMutator mutator, ICoverageAnalysisResult coverageAnalysisResult) { OriginalNode = originalNode; OriginalClass = originalClass; this.originalSyntaxRoot = originalSyntaxRoot; this.memberName = memberName; this.config = config; this.mutator = mutator; this.coverageAnalysisResult = coverageAnalysisResult; }
protected void Given_an_app_which_has_a_custom_test_runner() { Given_an_app(); config.ProjectFilters = new[] { "HasSurvivingMutants.MoreImplementation" }; config.SourceFileFilters = new[] { @"MoreImplementation\MorePartiallyTestedNumberComparison.cs" }; var binDir = Path.Combine(BaseDir, "XUnitTests", "bin", BuildConfig.AsString); config.TestAssemblyFilePaths = new[] { Path.Combine(binDir, "HasSurvivingMutants.XUnitTests.dll") }; config.CustomTestRunnerCommand = @"XUnitTests\run-example-xunit-tests.bat"; testRunner = new TestRunnerFactory().CreateCustomTestRunner(config.CustomTestRunnerCommand, BaseDir); coverageAnalysisResult = null; }
protected void Given_an_app_which_has_nunit_tests() { Given_an_app(); config.ProjectFilters = new[] { "HasSurvivingMutants.Implementation" }; config.SourceFileFilters = new[] { @"Implementation\*" }; var binDir = Path.Combine(BaseDir, "Tests", "bin", BuildConfig.AsString); config.TestAssemblyFilePaths = new[] { Path.Combine(binDir, "HasSurvivingMutants.Tests.dll") }; config.CustomTestRunnerCommand = null; testRunner = new TestRunnerFactory().CreateNUnitTestRunner(); coverageAnalysisResult = new CoverageAnalyser(SpyEventListener).AnalyseCoverage(config).Result; }
public static async Task <MutationJobList> Create(Config config, ICoverageAnalysisResult coverageAnalysisResult) { var jobs = new MutationJobList(config); var documentsToMutate = await config.FindMutatableDocuments(); for (var documentIndex = 0; documentIndex < documentsToMutate.Length; documentIndex++) { var documentToMutate = documentsToMutate[documentIndex]; var documentSyntaxRoot = await documentToMutate.GetSyntaxRootAsync(); var documentSemanticModel = await documentToMutate.GetSemanticModelAsync(); var nodesToMutate = documentSyntaxRoot.DescendantNodes().ToArray(); var isIgnoring = false; for (var nodeIndex = 0; nodeIndex < nodesToMutate.Length; nodeIndex++) { var nodeToMutate = nodesToMutate[nodeIndex]; var memberName = nodeToMutate.NameOfContainingMember(documentSemanticModel); if (memberName == null) { // The node is not within a member (e.g. it's a class or namespace declaration) // Or, the node is within a member, but the member is not one Fettle supports. // Either way, there is no code to mutate. continue; } if (coverageAnalysisResult != null && !coverageAnalysisResult.IsMemberCovered(memberName)) { continue; } if (Ignoring.NodeHasBeginIgnoreComment(nodeToMutate)) { isIgnoring = true; } else if (Ignoring.NodeHasEndIgnoreComment(nodeToMutate)) { isIgnoring = false; } if (isIgnoring) { continue; } foreach (var mutator in nodeToMutate.SupportedMutators()) { var job = new MutationJob( documentSyntaxRoot, nodeToMutate, documentToMutate, memberName, config, mutator, coverageAnalysisResult); var jobMetadata = new MutationJobMetadata { SourceFilePath = documentToMutate.FilePath, SourceFileIndex = documentIndex, SourceFilesTotal = documentsToMutate.Length, MemberName = memberName, SyntaxNodeIndex = nodeIndex, SyntaxNodesTotal = nodesToMutate.Length }; jobs.AddJob(job, jobMetadata); } } } return(jobs); }
internal static int Run( string[] args, ITestRunnerFactory testRunnerFactory, Func <ITestRunner, IEventListener, ICoverageAnalysisResult, IMutationTestRunner> mutationTestRunnerFactory, Func <IEventListener, ICoverageAnalyser> coverageAnalyserFactory, ISourceControlIntegration sourceControlIntegration, IOutputWriter outputWriter) { try { outputWriter.WriteLine($"Fettle v{AssemblyVersionInformation.AssemblyVersion}"); var parsedArgs = CommandLineArguments.Parse(args, outputWriter); if (!parsedArgs.Success) { return(ExitCodes.ConfigOrArgsAreInvalid); } var validationErrors = parsedArgs.Config.Validate().ToList(); if (validationErrors.Any()) { OutputValidationErrors(validationErrors, outputWriter); return(ExitCodes.ConfigOrArgsAreInvalid); } if (!string.IsNullOrEmpty(parsedArgs.Config.CustomTestRunnerCommand) && !parsedArgs.ConsoleOptions.SkipCoverageAnalysis) { WarnThatOptionsAreIncompatibleWithCoverageAnalysis(outputWriter); } if (parsedArgs.ConsoleOptions.ModificationsOnly) { var result = FindLocallyModifiedSourceFiles(sourceControlIntegration, parsedArgs.Config, outputWriter); if (!result.Success) { outputWriter.WriteFailureLine("Failed to find local modifications."); return(ExitCodes.UnexpectedError); } parsedArgs.Config.LocallyModifiedSourceFiles = result.Files; } if (!parsedArgs.Config.HasAnyMutatableDocuments().Result) { outputWriter.WriteLine("No source files found to mutate (or none matched the filters), exiting."); return(ExitCodes.Success); } var eventListener = CreateEventListener(outputWriter, parsedArgs.ConsoleOptions.Verbosity); ICoverageAnalysisResult coverageResult = null; var shouldDoCoverageAnalysis = !parsedArgs.Config.HasCustomTestRunnerCommand && !parsedArgs.ConsoleOptions.SkipCoverageAnalysis; if (shouldDoCoverageAnalysis) { var analyser = coverageAnalyserFactory(eventListener); coverageResult = AnalyseCoverage(analyser, outputWriter, parsedArgs.Config); if (!coverageResult.WasSuccessful) { OutputCoverageAnalysisError(coverageResult.ErrorDescription, outputWriter); return(ExitCodes.ConfigOrArgsAreInvalid); } } var testRunner = parsedArgs.Config.HasCustomTestRunnerCommand ? testRunnerFactory.CreateCustomTestRunner(parsedArgs.Config.CustomTestRunnerCommand, parsedArgs.Config.BaseDirectory) : testRunnerFactory.CreateNUnitTestRunner(); var mutationTestRunner = mutationTestRunnerFactory(testRunner, eventListener, coverageResult); var mutationTestResult = PerformMutationTesting(mutationTestRunner, parsedArgs.Config, outputWriter); if (mutationTestResult.Errors.Any()) { outputWriter.WriteFailureLine("Unable to perform mutation testing:"); mutationTestResult.Errors.ToList().ForEach(e => outputWriter.WriteFailureLine($"==> {e}")); { return(ExitCodes.ConfigOrArgsAreInvalid); } } if (mutationTestResult.SurvivingMutants.Any()) { OutputAllSurvivorInfo(mutationTestResult.SurvivingMutants, outputWriter, parsedArgs.Config); return(ExitCodes.SomeMutantsSurvived); } else { outputWriter.WriteSuccessLine("No mutants survived."); return(ExitCodes.Success); } } catch (Exception ex) { outputWriter.WriteFailureLine($"An error ocurred that Fettle didn't expect.{Environment.NewLine}{ex}"); return(ExitCodes.UnexpectedError); } }
public MutationTestRunner( ICoverageAnalysisResult coverageAnalysisResult, IEventListener eventListener = null) : this(new NUnitTestEngine(), coverageAnalysisResult, eventListener) { }