/// <summary> /// Starts a mutation test run /// </summary> /// <exception cref="StrykerInputException">For managed exceptions</exception> /// <param name="options">The user options</param> /// <param name="initialLogMessages"> /// Allows to pass log messages that occured before the mutation test. /// The messages will be written to the logger after it was configured. /// </param> public StrykerRunResult RunMutationTest(StrykerOptions options, IEnumerable <LogMessage> initialLogMessages = null) { var stopwatch = new Stopwatch(); stopwatch.Start(); var reporters = _reporterFactory.Create(options); SetupLogging(options, initialLogMessages); try { // Mutate _mutationTestProcesses = _projectOrchestrator.MutateProjects(options, reporters).ToList(); var rootComponent = AddRootFolderIfMultiProject(_mutationTestProcesses.Select(x => x.Input.ProjectInfo.ProjectContents).ToList(), options); _logger.LogInformation("{0} mutants created", rootComponent.Mutants.Count()); AnalyseCoverage(options); var readOnlyInputComponent = rootComponent.ToReadOnlyInputComponent(); // Report reporters.OnMutantsCreated(readOnlyInputComponent); var allMutants = rootComponent.Mutants.ToList(); // Filter foreach (var project in _mutationTestProcesses) { project.FilterMutants(); } var mutantsNotRun = allMutants.Where(x => x.ResultStatus == MutantStatus.NotRun).ToList(); if (!mutantsNotRun.Any()) { if (allMutants.Any(x => x.ResultStatus == MutantStatus.Ignored)) { _logger.LogWarning("It looks like all mutants with tests were excluded. Try a re-run with less exclusion!"); } if (allMutants.Any(x => x.ResultStatus == MutantStatus.NoCoverage)) { _logger.LogWarning("It looks like all non-excluded mutants are not covered by a test. Go add some tests!"); } if (!allMutants.Any()) { _logger.LogWarning("It\'s a mutant-free world, nothing to test."); } return(new StrykerRunResult(options, double.NaN)); } // Report reporters.OnStartMutantTestRun(mutantsNotRun); // Test foreach (var project in _mutationTestProcesses) { project.Test(project.Input.ProjectInfo.ProjectContents.Mutants.Where(x => x.ResultStatus == MutantStatus.NotRun).ToList()); } reporters.OnAllMutantsTested(readOnlyInputComponent); return(new StrykerRunResult(options, readOnlyInputComponent.GetMutationScore())); } catch (Exception ex) when(!(ex is StrykerInputException)) { _logger.LogError(ex, "An error occurred during the mutation test run "); throw; } finally { // log duration stopwatch.Stop(); _logger.LogInformation("Time Elapsed {0}", stopwatch.Elapsed); } }
/// <summary> /// Starts a mutation test run /// </summary> /// <param name="options">The user options</param> /// <param name="loggerFactory">This loggerfactory will be used to create loggers during the stryker run</param> /// <exception cref="InputException">For managed exceptions</exception> public StrykerRunResult RunMutationTest(IStrykerInputs inputs, ILoggerFactory loggerFactory, IProjectOrchestrator projectOrchestrator = null) { var stopwatch = new Stopwatch(); stopwatch.Start(); SetupLogging(loggerFactory); // Setup project orchestrator can't be done sooner since it needs logging projectOrchestrator ??= new ProjectOrchestrator(); var options = inputs.ValidateAll(); _logger.LogDebug("Stryker started with options: {@Options}", options); var reporters = _reporterFactory.Create(options); try { // Mutate _mutationTestProcesses = projectOrchestrator.MutateProjects(options, reporters).ToList(); IReadOnlyProjectComponent rootComponent = AddRootFolderIfMultiProject(_mutationTestProcesses.Select(x => x.Input.ProjectInfo.ProjectContents).ToList(), options); _logger.LogInformation("{0} mutants created", rootComponent.Mutants.Count()); AnalyseCoverage(options); // Filter foreach (var project in _mutationTestProcesses) { project.FilterMutants(); } // Report reporters.OnMutantsCreated(rootComponent); var allMutants = rootComponent.Mutants; var mutantsNotRun = rootComponent.NotRunMutants().ToList(); if (!mutantsNotRun.Any()) { if (allMutants.Any(x => x.ResultStatus == MutantStatus.Ignored)) { _logger.LogWarning("It looks like all mutants with tests were ignored. Try a re-run with less ignoring!"); } if (allMutants.Any(x => x.ResultStatus == MutantStatus.NoCoverage)) { _logger.LogWarning("It looks like all non-ignored mutants are not covered by a test. Go add some tests!"); } if (allMutants.Any(x => x.ResultStatus == MutantStatus.CompileError)) { _logger.LogWarning("It looks like all mutants resulted in compile errors. Mutants sure are strange!"); } if (!allMutants.Any()) { _logger.LogWarning("It\'s a mutant-free world, nothing to test."); } reporters.OnAllMutantsTested(rootComponent); return(new StrykerRunResult(options, rootComponent.GetMutationScore())); } // Report reporters.OnStartMutantTestRun(mutantsNotRun); // Test foreach (var project in _mutationTestProcesses) { project.Test(project.Input.ProjectInfo.ProjectContents.Mutants.Where(x => x.ResultStatus == MutantStatus.NotRun).ToList()); project.Restore(); } reporters.OnAllMutantsTested(rootComponent); return(new StrykerRunResult(options, rootComponent.GetMutationScore())); } #if !DEBUG catch (Exception ex) when(!(ex is InputException)) // let the exception be caught by the debugger when in debug { _logger.LogError(ex, "An error occurred during the mutation test run "); throw; } #endif finally { // log duration stopwatch.Stop(); _logger.LogInformation("Time Elapsed {0}", stopwatch.Elapsed); } }