示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
                }
            }
        }
示例#5
0
 private async Task RunMuTest(MuTestOptions options)
 {
     PrintAsciiName();
     await _muTest.RunMutationTest(options);
 }