public MuTestOptions Build() { var muTestOptions = new MuTestOptions { TestSolution = GetOption(TestSolution.Value(), CliOptions.TestSolution), SourceClass = GetOption(SourceClass.Value(), CliOptions.SourceClass), SourceHeader = GetOption(SourceHeader.Value(), CliOptions.SourceHeader), TestProject = GetOption(TestProject.Value(), CliOptions.TestProject), TestClass = GetOption(TestClass.Value(), CliOptions.TestClass), EnableDiagnostics = GetOption(Diagnostics.Value(), CliOptions.EnableDiagnostics), ConcurrentTestRunners = GetOption(Parallel.Value(), CliOptions.Parallel), MutantsPerLine = GetOption(MutantsPerLine.Value(), CliOptions.MutantsPerLine), SurvivedThreshold = GetOption(SurvivedThreshold.Value(), CliOptions.SurvivedThreshold), KilledThreshold = GetOption(KilledThreshold.Value(), CliOptions.KilledThreshold), InIsolation = GetOption(InIsolation.Value(), CliOptions.InIsolation), DisableBuildOptimization = GetOption(DisableBuildOptimization.Value(), CliOptions.DisableBuildOptimization), IncludeBuildEvents = GetOption(IncludeBuildEvents.Value(), CliOptions.IncludeBuildEvents), OutputPath = GetOption(OutputPath.Value(), CliOptions.OutputPath), Configuration = GetOption(Configuration.Value(), CliOptions.BuildConfiguration), Platform = GetOption(Platform.Value(), CliOptions.Platform), SpecificLines = GetOption(SpecificLines.Value(), CliOptions.SpecificLineRange) }; muTestOptions.ValidateOptions(); return(muTestOptions); }
public MuTestOptions Build() { var muTestOptions = new MuTestOptions { SourceProjectParameter = GetOption(SourceProject.Value(), CliOptions.SourceProject), SourceProjectLibraryParameter = GetOption(SourceLib.Value(), CliOptions.SourceLib), SourceClassParameter = GetOption(SourceClass.Value(), CliOptions.SourceClass), TestProjectParameter = GetOption(TestProject.Value(), CliOptions.TestProject), TestProjectLibraryParameter = GetOption(TestLib.Value(), CliOptions.TestLib), TestClassParameter = GetOption(TestClass.Value(), CliOptions.TestClass), ExecuteAllTests = GetOption(ExecuteAllTests.Value(), CliOptions.ExecuteAllTests), SkipTestProjectBuild = GetOption(SkipTestProjectBuild.Value(), CliOptions.SkipTestProjectBuild), IncludePartialClasses = GetOption(IncludePartialClasses.Value(), CliOptions.IncludePartialClasses), AnalyzeExternalCoveredClasses = GetOption(AnalyzeExternalCoveredClasses.Value(), CliOptions.AnalyzeExternalCoveredClasses), IncludeNestedClasses = GetOption(IncludeNestedClasses.Value(), CliOptions.IncludeNestedClasses), UseClassFilter = GetOption(UseClassFilter.Value(), CliOptions.UseClassFilter), X64TargetPlatform = GetOption(X64.Value(), CliOptions.X64TargetPlatform), BuildInReleaseModeParameter = GetOption(ReleaseMode.Value(), CliOptions.BuildInReleaseMode), EnableDiagnostics = GetOption(Diagnostics.Value(), CliOptions.EnableDiagnostics), OptimizeTestProject = GetOption(OptimizeTestProject.Value(), CliOptions.OptimizeTestProject), ConcurrentTestRunners = GetOption(Parallel.Value(), CliOptions.Parallel), SurvivedThreshold = GetOption(SurvivedThreshold.Value(), CliOptions.SurvivedThreshold), KilledThreshold = GetOption(KilledThreshold.Value(), CliOptions.KilledThreshold), OutputPathParameter = GetOption(OutputPath.Value(), CliOptions.OutputPath), NoCoverage = GetOption(NoCoverage.Value(), CliOptions.NoCoverage), RegEx = GetOption(RegEx.Value(), CliOptions.Regex), Specific = GetOption(Specific.Value(), CliOptions.Specific), ClassName = GetOption(ClassName.Value(), CliOptions.ClassName), ProcessWholeProject = GetOption(ProcessWholeProject.Value(), CliOptions.ProcessWholeProject), TestExecutionThreshold = GetOption(FindTestTime.Value(), CliOptions.TestExecutionThreshold), MutantsPerLine = GetOption(MutantsPerLine.Value(), CliOptions.MutantsPerLine) }; muTestOptions .MultipleSourceClasses .AddRange(GetOption(MultipleSourceClasses.Value(), CliOptions.MultipleSourceClasses).Distinct()); muTestOptions .MultipleTestClasses .AddRange(GetOption(MultipleTestClasses.Value(), CliOptions.MultipleTestClasses).Distinct()); muTestOptions.ValidateOptions(); return(muTestOptions); }
public async Task RunMutationTest(MuTestOptions options) { if (!File.Exists(MuTestSettings.MSBuildPath)) { throw new MuTestInputException($"Unable to locate MSBuild Path at {MuTestSettings.MSBuildPath}. Please update MSBuildPath in MuTest.Console.exe.config if you are using different version"); } if (!File.Exists(MuTestSettings.VSTestConsolePath)) { throw new MuTestInputException($"Unable to locate VS Test Console Path at {MuTestSettings.VSTestConsolePath}. Please update VSTestConsolePath in MuTest.Console.exe.config if you are using different version"); } if (!File.Exists(MuTestSettings.RunSettingsPath)) { throw new MuTestInputException($"Unable to locate tests run settings path at {MuTestSettings.RunSettingsPath}. Please update RunSettingsPath in MuTest.Console.exe.config if you are using different location"); } _stopwatch = new Stopwatch(); _stopwatch.Start(); _options = options; if (!_options.SkipTestProjectBuild) { var originalProject = _options.TestProjectParameter; if (_options.OptimizeTestProject && _options.MultipleTargetClasses.Count == 1) { var targetClass = _options.MultipleTargetClasses.First(); _options.TestProjectParameter = _options .TestProjectParameter .UpdateTestProject(targetClass.TestClassPath.GetClass().ClassName()); } await ExecuteBuild(); if (!originalProject.Equals(_options.TestProjectParameter, StringComparison.InvariantCultureIgnoreCase)) { if (File.Exists(_options.TestProjectParameter)) { File.Delete(_options.TestProjectParameter); } _options.TestProjectParameter = originalProject; } } var serial = 1; _chalk.Default("\n*********************************** Matched Classes ***********************************"); foreach (var srcClass in _options.MultipleTargetClasses) { _chalk.Green($"\n{serial++}. {srcClass.ClassName} in {srcClass.ClassPath}"); } _chalk.Default("\n***************************************************************************************"); var projectSummary = new ProjectSummary { SourceProject = _options.SourceProjectParameter, TestProject = _options.TestProjectParameter }; var mutantAnalyzer = new MutantAnalyzer(_chalk, MuTestSettings) { ProcessWholeProject = _options.ProcessWholeProject, BuildInReleaseMode = _options.BuildInReleaseModeParameter, ConcurrentTestRunners = _options.ConcurrentTestRunners, EnableDiagnostics = _options.EnableDiagnostics, ExecuteAllTests = _options.ExecuteAllTests, IncludeNestedClasses = _options.IncludeNestedClasses, IncludePartialClasses = _options.IncludePartialClasses || _options.UseClassFilter || _options.ExecuteAllTests, KilledThreshold = _options.KilledThreshold, NoCoverage = _options.NoCoverage, RegEx = _options.RegEx, Specific = _options.Specific, SurvivedThreshold = _options.SurvivedThreshold, TestProject = _options.TestProjectParameter, TestProjectLibrary = _options.TestProjectLibraryParameter, UseClassFilter = _options.UseClassFilter, X64TargetPlatform = _options.X64TargetPlatform, TestExecutionTime = _options.TestExecutionThreshold, MutantsPerLine = _options.MutantsPerLine }; foreach (var targetClass in _options.MultipleTargetClasses) { mutantAnalyzer.TestClass = targetClass.TestClassPath; mutantAnalyzer.UseExternalCodeCoverage = false; mutantAnalyzer.MutantExecutor = null; var sourceClass = targetClass.ClassPath; var className = targetClass.ClassName; mutantAnalyzer.SourceProjectLibrary = _options.SourceProjectLibraryParameter; try { var sourceHash = sourceClass.GetCodeFileContent().ComputeHash(); var testHash = targetClass.TestClassPath.GetCodeFileContent().ComputeHash(); var hash = $"{sourceHash}-{testHash}".ComputeHash(); await GetFromDB(hash); if (_source != null) { var testClaz = targetClass.TestClassPath.GetClass(); var loader = new SemanticsClassDeclarationLoader(); _source.Claz = loader.Load(sourceClass, _options.SourceProjectParameter, className); _source.ClassLibrary = _options.SourceProjectLibraryParameter; _source.ClassProject = _options.SourceProjectParameter; _source.FilePath = sourceClass; _source.TestClaz = new TestClassDetail { Claz = new ClassDeclaration(testClaz), FilePath = targetClass.TestClassPath, ClassProject = _options.TestProjectParameter, FullName = testClaz.FullName(), ClassLibrary = _options.TestProjectLibraryParameter, X64TargetPlatform = _options.X64TargetPlatform }; } if (_source == null) { mutantAnalyzer.ExternalCoveredMutants.Clear(); _source = await mutantAnalyzer.Analyze(sourceClass, className, _options.SourceProjectParameter); _source.SHA256 = hash; _source.StoreToDb = true; if (_source.ExternalCoveredClassesIncluded.Any() && _options.AnalyzeExternalCoveredClasses) { _chalk.Yellow("\n\nAnalyzing External Coverage..."); mutantAnalyzer.UseExternalCodeCoverage = true; foreach (var acc in _source.ExternalCoveredClassesIncluded) { mutantAnalyzer.ExternalCoveredMutants.AddRange(acc.MutantsLines); var projectFile = new FileInfo(acc.ClassPath).FindProjectFile(); mutantAnalyzer.SourceProjectLibrary = projectFile.FindLibraryPath()?.FullName; if (!string.IsNullOrWhiteSpace(mutantAnalyzer.SourceProjectLibrary)) { var accClass = await mutantAnalyzer.Analyze( acc.ClassPath, acc.ClassName, projectFile.FullName); accClass.CalculateMutationScore(); if (accClass.MutationScore.Survived == 0) { acc.ZeroSurvivedMutants = true; } } } mutantAnalyzer.ExternalCoveredMutants.Clear(); } } } catch (Exception ex) when(!(ex is MuTestInputException)) { throw; } finally { MutantExecutor = mutantAnalyzer.MutantExecutor ?? new MutantExecutor(_source, MuTestSettings); _stopwatch.Stop(); if (_source != null) { await GenerateReports(); if (!string.IsNullOrWhiteSpace(_options.ProcessWholeProject)) { projectSummary.Classes.Add(new ClassSummary { TargetClass = new TargetClass { ClassPath = _source.FilePath, ClassName = _source.Claz.Syntax.FullName(), TestClassPath = _source.TestClaz.FilePath }, MutationScore = _source.MutationScore, Coverage = _source.Coverage ?? new Coverage() }); } } } } if (!string.IsNullOrWhiteSpace(_options.ProcessWholeProject)) { projectSummary.CalculateMutationScore(); var builder = new StringBuilder(HtmlTemplate); builder.AppendLine("<fieldset style=\"margin-bottom:10; margin-top:10\">"); builder.AppendLine("Mutation Report".PrintImportantWithLegend()); builder.Append(" ".PrintWithPreTag()); builder.Append($"{"Source Project:".PrintImportant()} {projectSummary.SourceProject}".PrintWithPreTag()); builder.Append($"{"Test Project :".PrintImportant()} {projectSummary.TestProject}".PrintWithPreTag()); builder.Append(" ".PrintWithPreTag()); builder.AppendLine("<fieldset style=\"margin-bottom:10; margin-top:10\">"); builder.AppendLine("Classes Mutation".PrintImportantWithLegend()); foreach (var claz in projectSummary.Classes) { builder.AppendLine("<fieldset style=\"margin-bottom:10; margin-top:10\">"); builder.AppendLine($"{claz.TargetClass.ClassName} [{claz.TargetClass.ClassPath}]".PrintImportantWithLegend(color: Colors.BlueViolet)); builder.Append($"{claz.MutationScore.Mutation} - {claz.MutationScore}".PrintWithPreTagWithMarginImportant()); builder.Append($"Code Coverage - {claz.Coverage}".PrintWithPreTagWithMarginImportant()); builder.AppendLine("</fieldset>"); } builder.AppendLine("</fieldset>"); builder.AppendLine("<fieldset style=\"margin-bottom:10; margin-top:10\">"); builder.AppendLine("ProjectWise Summary".PrintImportantWithLegend()); builder.Append(projectSummary.MutationScore.ToString().PrintWithPreTagWithMarginImportant(color: Colors.BlueViolet)); builder.Append($"Coverage: Mutation({projectSummary.MutationScore.Mutation}) {projectSummary.Coverage}".PrintWithPreTagWithMarginImportant(color: Colors.Blue)); builder.AppendLine("</fieldset>"); builder.AppendLine("</fieldset>"); CreateHtmlReport(builder, ProjectSummary); await CreateJsonReport(ProjectSummary, projectSummary); } }
public async Task RunMutationTest(MuTestOptions options) { try { if (!File.Exists(MuTestSettings.MSBuildPath)) { throw new MuTestInputException($"Unable to locate MSBuild Path at {MuTestSettings.MSBuildPath}. Please update MSBuildPath in MuTest.Console.exe.config if you are using different version"); } _stopwatch = new Stopwatch(); _stopwatch.Start(); _options = options; _chalk.Default("\nPreparing Required Files...\n"); DirectoryFactory.NumberOfMutantsExecutingInParallel = _options.ConcurrentTestRunners; _cppClass = new CppClass { Configuration = _options.Configuration, SourceClass = _options.SourceClass, Platform = _options.Platform, TestClass = _options.TestClass, TestProject = _options.TestProject, Target = _options.Target, SourceHeader = _options.SourceHeader, TestSolution = _options.TestSolution, IncludeBuildEvents = _options.IncludeBuildEvents }; Context = !_options.InIsolation ? DirectoryFactory.PrepareTestFiles(_cppClass) : DirectoryFactory.PrepareSolutionFiles(_cppClass); if (Context.TestContexts.Any()) { await ExecuteBuild(); await ExecuteTests(); if (!_options.DisableBuildOptimization) { Context.EnableBuildOptimization = true; } _chalk.Default("\nRunning Mutation Analysis...\n"); var defaultMutants = CppMutantOrchestrator.GetDefaultMutants(_options.SourceClass, _options.SpecificLines).ToList(); defaultMutants = _aridNodeMutantFilterer.FilterMutants(defaultMutants).ToList(); defaultMutants = _mutantsSelector.SelectMutants(_options.MutantsPerLine, defaultMutants).ToList(); _cppClass.Mutants.AddRange(defaultMutants); if (_cppClass.CoveredLineNumbers.Any()) { foreach (var mutant in _cppClass.Mutants) { if (_cppClass.CoveredLineNumbers.All(x => x != mutant.Mutation.LineNumber)) { mutant.ResultStatus = MutantStatus.NotCovered; } else if (mutant.Mutation.EndLineNumber > mutant.Mutation.LineNumber) { if (!_cppClass.CoveredLineNumbers.Any(x => x > mutant.Mutation.LineNumber && x <= mutant.Mutation.EndLineNumber)) { mutant.ResultStatus = MutantStatus.Skipped; } } } } _chalk.Default($"\nNumber of Mutants: {_cppClass.Mutants.Count}\n"); var sourceHash = _cppClass .SourceClass .GetCodeFileContent() .ComputeHash(); var testHash = _cppClass .TestClass .GetCodeFileContent() .ComputeHash(); _cppClass.Sha256 = (sourceHash + testHash).ComputeHash(); var data = await _client.GetFileDataFromStorage(_cppClass.Sha256); _cppClass.StoreInDb = true; if (data != null) { var cppClass = JsonConvert.DeserializeObject <CppClass>(data); cppClass.StoreInDb = false; cppClass.SourceClass = _cppClass.SourceClass; cppClass.SourceHeader = _cppClass.SourceHeader; cppClass.TestClass = _cppClass.TestClass; cppClass.TestProject = _cppClass.TestProject; cppClass.Configuration = _cppClass.Configuration; cppClass.Target = _cppClass.Target; cppClass.Platform = _cppClass.Platform; cppClass.TestSolution = _cppClass.TestSolution; cppClass.IncludeBuildEvents = _cppClass.IncludeBuildEvents; _cppClass = cppClass; } MutantsExecutor = new CppMutantExecutor(_cppClass, Context, MuTestSettings) { EnableDiagnostics = _options.EnableDiagnostics, KilledThreshold = _options.KilledThreshold, SurvivedThreshold = _options.SurvivedThreshold, NumberOfMutantsExecutingInParallel = _options.ConcurrentTestRunners }; _totalMutants = _cppClass.NotRunMutants.Count; _mutantProgress = 0; if (_cppClass.Mutants.Any() && data == null) { MutantsExecutor.MutantExecuted += MutantAnalyzerOnMutantExecuted; await MutantsExecutor.ExecuteMutants(); } await GenerateReports(); } } finally { if (Context != null) { DirectoryFactory.DeleteTestFiles(Context); } } }
private async Task RunMuTest(MuTestOptions options) { PrintAsciiName(); await _muTest.RunMutationTest(options); }