diff --git a/Directory.Packages.props b/Directory.Packages.props index eba94e254..70fd039bb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -12,7 +12,7 @@ 4.12.0 17.13.0 - 6.13.2 + 6.14.0 2.0.0 3.0.2 @@ -54,18 +54,18 @@ - + - + - + - + diff --git a/Documentation/GlobalTool.md b/Documentation/GlobalTool.md index e91f67c9d..6b9161b4f 100644 --- a/Documentation/GlobalTool.md +++ b/Documentation/GlobalTool.md @@ -275,5 +275,4 @@ Coverlet outputs specific exit codes to better support build automation systems 2 - Coverage percentage is below threshold. 3 - Test fails and also coverage percentage is below threshold. 101 - General exception occurred during coverlet process. -102 - Missing options or invalid arguments for coverlet process. ``` diff --git a/global.json b/global.json index 6dfc6666e..8b2877a60 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.407" + "version": "8.0.409" } } diff --git a/src/coverlet.collector/coverlet.collector.csproj b/src/coverlet.collector/coverlet.collector.csproj index 7630bb845..fa18b7b3c 100644 --- a/src/coverlet.collector/coverlet.collector.csproj +++ b/src/coverlet.collector/coverlet.collector.csproj @@ -27,7 +27,6 @@ tonerdo MIT https://github.com/coverlet-coverage/coverlet - https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true coverlet-icon.png false Coverlet is a cross platform code coverage library for .NET, with support for line, branch and method coverage. diff --git a/src/coverlet.console/ExitCodes.cs b/src/coverlet.console/ExitCodes.cs index 93a7d395f..616bf8b10 100644 --- a/src/coverlet.console/ExitCodes.cs +++ b/src/coverlet.console/ExitCodes.cs @@ -28,10 +28,5 @@ internal enum CommandExitCodes /// Indicates exception occurred during Coverlet process. /// Exception = 101, - - /// - /// Indicates missing options or empty arguments for Coverlet process. - /// - CommandParsingException = 102 } diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index ec763612d..93e595683 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -25,6 +25,7 @@ namespace Coverlet.Console { public static class Program { + static int s_exitCode; static int Main(string[] args) { var moduleOrAppDirectory = new Argument("path", "Path to the test assembly or application directory."); @@ -32,9 +33,9 @@ static int Main(string[] args) var targs = new Option(["--targetargs", "-a"], "Arguments to be passed to the test runner.") { Arity = ArgumentArity.ZeroOrOne }; var output = new Option(["--output", "-o"], "Output of the generated coverage report") { Arity = ArgumentArity.ZeroOrOne }; var verbosity = new Option(["--verbosity", "-v"], () => LogLevel.Normal, "Sets the verbosity level of the command. Allowed values are quiet, minimal, normal, detailed.") { Arity = ArgumentArity.ZeroOrOne }; - var formats = new Option(["--format", "-f"], () => ["json"], "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; + var formats = new Option(aliases: ["--format", "-f"], getDefaultValue: () => ["json"], description: "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }.FromAmong("json", "lcov", "opencover", "cobertura", "teamcity"); var threshold = new Option("--threshold", "Exits with error if the coverage % is below value.") { Arity = ArgumentArity.ZeroOrOne }; - Option> thresholdTypes = new Option>("--threshold-type", () => new List(new string[] { "line", "branch", "method" }), "Coverage type to apply the threshold to.").FromAmong("line", "branch", "method"); + Option> thresholdTypes = new Option>("--threshold-type", () => ["line", "branch", "method"], "Coverage type to apply the threshold to.").FromAmong("line", "branch", "method"); var thresholdStat = new Option("--threshold-stat", () => ThresholdStatistic.Minimum, "Coverage statistic used to enforce the threshold value.") { Arity = ArgumentArity.ZeroOrOne }; var excludeFilters = new Option("--exclude", "Filter expressions to exclude specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var includeFilters = new Option("--include", "Filter expressions to include only specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; @@ -47,7 +48,7 @@ static int Main(string[] args) var mergeWith = new Option("--merge-with", "Path to existing coverage result to merge.") { Arity = ArgumentArity.ZeroOrOne }; var useSourceLink = new Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.") { Arity = ArgumentArity.Zero }; var doesNotReturnAttributes = new Option("--does-not-return-attribute", "Attributes that mark methods that do not return") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; - var excludeAssembliesWithoutSources = new Option("--exclude-assemblies-without-sources", "Specifies behavior of heuristic to ignore assemblies with missing source documents.") { Arity = ArgumentArity.ZeroOrOne }; + Option excludeAssembliesWithoutSources = new Option("--exclude-assemblies-without-sources", () => "MissingAll", "Specifies behavior of heuristic to ignore assemblies with missing source documents.").FromAmong("MissingAll", "MissingAny", "None"); var sourceMappingFile = new Option("--source-mapping-file", "Specifies the path to a SourceRootsMappings file.") { Arity = ArgumentArity.ZeroOrOne }; RootCommand rootCommand = new() @@ -175,7 +176,7 @@ string sourceMappingFile // Adjust log level based on user input. logger.Level = verbosity; - int exitCode = (int)CommandExitCodes.Success; + s_exitCode = (int)CommandExitCodes.Success; try { @@ -357,44 +358,44 @@ string sourceMappingFile logger.LogInformation(coverageTable.ToStringAlternative()); if (process.ExitCode > 0) { - exitCode += (int)CommandExitCodes.TestFailed; + s_exitCode = (int)CommandExitCodes.TestFailed; } ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStat); if (thresholdTypeFlags != ThresholdTypeFlags.None) { - exitCode += (int)CommandExitCodes.CoverageBelowThreshold; - var exceptionMessageBuilder = new StringBuilder(); + s_exitCode = (int)CommandExitCodes.CoverageBelowThreshold; + var errorMessageBuilder = new StringBuilder(); if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None) { - exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Line]}"); + errorMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Line]}"); } if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None) { - exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Branch]}"); + errorMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Branch]}"); } if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None) { - exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Method]}"); + errorMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Method]}"); } - throw new InvalidOperationException(exceptionMessageBuilder.ToString()); + logger.LogError(errorMessageBuilder.ToString()); } - return Task.FromResult(exitCode); + return Task.FromResult(s_exitCode); } catch (Win32Exception we) when (we.Source == "System.Diagnostics.Process") { logger.LogError($"Start process '{target}' failed with '{we.Message}'"); - return Task.FromResult(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception); + return Task.FromResult(s_exitCode > 0 ? s_exitCode : (int)CommandExitCodes.Exception); } catch (Exception ex) { logger.LogError(ex.Message); - return Task.FromResult(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception); + return Task.FromResult(s_exitCode > 0 ? s_exitCode : (int)CommandExitCodes.Exception); } } diff --git a/src/coverlet.console/coverlet.console.csproj b/src/coverlet.console/coverlet.console.csproj index 2a7181b18..c2798a2a1 100644 --- a/src/coverlet.console/coverlet.console.csproj +++ b/src/coverlet.console/coverlet.console.csproj @@ -16,7 +16,6 @@ coverage;testing;unit-test;lcov;opencover;quality GlobalTool.md https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/Changelog.md - https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true coverlet-icon.png https://github.com/coverlet-coverage/coverlet MIT diff --git a/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj b/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj index c04e823b0..08e532b4f 100644 --- a/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj +++ b/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj @@ -28,7 +28,6 @@ tonerdo MIT https://github.com/coverlet-coverage/coverlet - https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true coverlet-icon.png false true diff --git a/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj b/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj index 36bc43a36..a7ce141f5 100644 --- a/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj +++ b/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/coverlet.integration.template/DeepThought.cs b/test/coverlet.integration.template/DeepThought.cs index e2a3f4b9c..998a001a2 100644 --- a/test/coverlet.integration.template/DeepThought.cs +++ b/test/coverlet.integration.template/DeepThought.cs @@ -1,10 +1,21 @@ -namespace Coverlet.Integration.Template +namespace Coverlet.Integration.Template { - public class DeepThought + public class DeepThought + { + public int AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything() { - public int AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything() - { - return 42; - } + return 42; } + + // This method is not covered by any test + // It is here to demonstrate how Coverlet will report on untested code + // required for Coverlet.Integration.Tests.DotnetGlobalTools.StandAloneThreshold + // required for Coverlet.Integration.Tests.DotnetGlobalTools.DotnetToolThreshold + public void TheUntestedMethod() + { +#pragma warning disable CS0219 // Variable is assigned but its value is never used + string s = "this will never be covered by any test"; +#pragma warning restore CS0219 // Variable is assigned but its value is never used + } + } } diff --git a/test/coverlet.integration.tests/DotnetTool.cs b/test/coverlet.integration.tests/DotnetTool.cs index 91e989f02..19c45b305 100644 --- a/test/coverlet.integration.tests/DotnetTool.cs +++ b/test/coverlet.integration.tests/DotnetTool.cs @@ -35,13 +35,14 @@ public void DotnetTool() string outputPath = $"{clonedTemplateProject.ProjectRootPath}{Path.DirectorySeparatorChar}coverage.json"; DotnetCli($"build -f {_buildTargetFramework} {clonedTemplateProject.ProjectRootPath}", out string buildOutput, out string buildError); string publishedTestFile = clonedTemplateProject.GetFiles("*" + ClonedTemplateProject.AssemblyName + ".dll").Single(f => !f.Contains("obj") && !f.Contains("ref")); - RunCommand(coverletToolCommandPath, $"\"{publishedTestFile}\" --target \"dotnet\" --targetargs \"test {Path.Combine(clonedTemplateProject.ProjectRootPath, ClonedTemplateProject.ProjectFileName)} --no-build\" --include-test-assembly --output \"{outputPath}\"", out string standardOutput, out string standardError); + int cmdExitCode = RunCommand(coverletToolCommandPath, $"\"{publishedTestFile}\" --target \"dotnet\" --targetargs \"test {Path.Combine(clonedTemplateProject.ProjectRootPath, ClonedTemplateProject.ProjectFileName)} --no-build\" --include-test-assembly --output \"{outputPath}\"", out string standardOutput, out string standardError); if (!string.IsNullOrEmpty(standardError)) { _output.WriteLine(standardError); } Assert.Contains("Passed!", standardOutput); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); + Assert.Equal((int)CommandExitCodes.Success, cmdExitCode); } [Fact] @@ -53,14 +54,14 @@ public void StandAlone() string outputPath = $"{clonedTemplateProject.ProjectRootPath}{Path.DirectorySeparatorChar}coverage.json"; DotnetCli($"build -f {_buildTargetFramework} {clonedTemplateProject.ProjectRootPath}", out string buildOutput, out string buildError); string publishedTestFile = clonedTemplateProject.GetFiles("*" + ClonedTemplateProject.AssemblyName + ".dll").Single(f => !f.Contains("obj") && !f.Contains("ref")); - RunCommand(coverletToolCommandPath, $"\"{Path.GetDirectoryName(publishedTestFile)}\" --target \"dotnet\" --targetargs \"{publishedTestFile}\" --output \"{outputPath}\"", out string standardOutput, out string standardError); + int cmdExitCode = RunCommand(coverletToolCommandPath, $"\"{Path.GetDirectoryName(publishedTestFile)}\" --target \"dotnet\" --targetargs \"{publishedTestFile}\" --output \"{outputPath}\"", out string standardOutput, out string standardError); if (!string.IsNullOrEmpty(standardError)) { _output.WriteLine(standardError); } - //Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); + Assert.Equal((int)CommandExitCodes.Success, cmdExitCode); } [Fact] @@ -82,13 +83,11 @@ public void StandAloneThreshold() // make standard output available in trx file _output.WriteLine(standardOutput); } - //Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); - //Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); - // this messages are now in stderr available but standardError stream is empty in test environment - //Assert.Contains("The minimum line coverage is below the specified 80", standardError); - //Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); + Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); + Assert.Contains("The minimum line coverage is below the specified 80", standardOutput); + Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); } [Fact] @@ -110,12 +109,11 @@ public void StandAloneThresholdLine() // make standard output available in trx file _output.WriteLine(standardOutput); } - // Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); - //Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); - //Assert.Contains("The minimum line coverage is below the specified 80", standardError); - //Assert.DoesNotContain("The minimum method coverage is below the specified 80", standardOutput); + Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); + Assert.Contains("The minimum line coverage is below the specified 80", standardOutput); + Assert.DoesNotContain("The minimum method coverage is below the specified 80", standardOutput); } [Fact] @@ -137,12 +135,95 @@ public void StandAloneThresholdLineAndMethod() // make standard output available in trx file _output.WriteLine(standardOutput); } - // Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); - //Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); - //Assert.Contains("The minimum line coverage is below the specified 80", standardError); - //Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); + Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); + Assert.Contains("The minimum line coverage is below the specified 80", standardOutput); + Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); + } + + [Fact] + public void ExcludeAssembliesWithoutSources_WrongValue() + { + using ClonedTemplateProject clonedTemplateProject = CloneTemplateProject(); + UpdateNugetConfigWithLocalPackageFolder(clonedTemplateProject.ProjectRootPath!); + string coverletToolCommandPath = InstallTool(clonedTemplateProject.ProjectRootPath!); + string outputPath = $"{clonedTemplateProject.ProjectRootPath}{Path.DirectorySeparatorChar}coverage.json"; + + // Build the test project + DotnetCli($"build -f {_buildTargetFramework} {clonedTemplateProject.ProjectRootPath}", + out string buildOutput, + out string buildError); + + string publishedTestFile = clonedTemplateProject.GetFiles("*" + ClonedTemplateProject.AssemblyName + ".dll") + .Single(f => !f.Contains("obj") && !f.Contains("ref")); + + // Run coverage with exclude-assemblies-without-sources parameter + int cmdExitCode = RunCommand( + coverletToolCommandPath, + $"\"{publishedTestFile}\" --target \"dotnet\" " + + $"--targetargs \"test {Path.Combine(clonedTemplateProject.ProjectRootPath, ClonedTemplateProject.ProjectFileName)} --no-build\" " + + $"--exclude-assemblies-without-sources nonsense " + + $"--output \"{outputPath}\"", + out string standardOutput, + out string standardError); + + if (!string.IsNullOrEmpty(standardError)) + { + _output.WriteLine(standardError); + } + else + { + _output.WriteLine(standardOutput); + } + + // Verify results + Assert.Contains("Argument 'nonsense' not recognized. Must be one of:\t'MissingAll'\t'MissingAny'\t'None'", standardError); + } + + [Theory] + [InlineData("MissingAll")] + [InlineData("MissingAny")] + [InlineData("None")] + public void ExcludeAssembliesWithoutSources_DifferentModes(string mode) + { + using ClonedTemplateProject clonedTemplateProject = CloneTemplateProject(); + UpdateNugetConfigWithLocalPackageFolder(clonedTemplateProject.ProjectRootPath!); + string coverletToolCommandPath = InstallTool(clonedTemplateProject.ProjectRootPath!); + string outputPath = $"{clonedTemplateProject.ProjectRootPath}{Path.DirectorySeparatorChar}coverage.json"; + + // Build the test project + DotnetCli($"build -f {_buildTargetFramework} {clonedTemplateProject.ProjectRootPath}", + out string buildOutput, + out string buildError); + + string publishedTestFile = clonedTemplateProject.GetFiles("*" + ClonedTemplateProject.AssemblyName + ".dll") + .Single(f => !f.Contains("obj") && !f.Contains("ref")); + + // Run coverage with different exclude-assemblies-without-sources modes + int cmdExitCode = RunCommand( + coverletToolCommandPath, + $"\"{publishedTestFile}\" --target \"dotnet\" " + + $"--targetargs \"test {Path.Combine(clonedTemplateProject.ProjectRootPath, ClonedTemplateProject.ProjectFileName)} --no-build\" " + + $"--exclude-assemblies-without-sources {mode} " + + $"--output \"{outputPath}\"", + out string standardOutput, + out string standardError); + + if (!string.IsNullOrEmpty(standardError)) + { + _output.WriteLine(standardError); + } + else + { + _output.WriteLine(standardOutput); + } + + // Verify basic execution + Assert.Empty(standardError); + Assert.True(File.Exists(outputPath), "Coverage output file should exist"); + Assert.Equal((int)CommandExitCodes.Success, cmdExitCode); + Assert.Contains("Passed!", standardOutput); } } } diff --git a/test/coverlet.integration.tests/Msbuild.cs b/test/coverlet.integration.tests/Msbuild.cs index abb784d10..53afa3fc5 100644 --- a/test/coverlet.integration.tests/Msbuild.cs +++ b/test/coverlet.integration.tests/Msbuild.cs @@ -14,6 +14,7 @@ public class Msbuild : BaseTest private readonly string _buildConfiguration; private readonly string _buildTargetFramework; private readonly ITestOutputHelper _output; + private static readonly string s_expectedResult = "| coverletsamplelib.integration.template | 50% | 100% | 50% |"; public Msbuild(ITestOutputHelper output) { @@ -45,7 +46,7 @@ public void TestMsbuild() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"coverage.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -66,7 +67,7 @@ public void TestMsbuild_NoCoverletOutput() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"coverage.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -87,7 +88,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameWithoutExtension() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -99,7 +100,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameExtension() using ClonedTemplateProject clonedTemplateProject = PrepareTemplateProject(); Assert.Equal(0, DotnetCli($"test -c {_buildConfiguration} -f {_buildTargetFramework} \"{clonedTemplateProject.ProjectRootPath}\" /p:CollectCoverage=true /p:Include=\"[{ClonedTemplateProject.AssemblyName}]*DeepThought\" /p:IncludeTestAssembly=true /p:CoverletOutput=\"{clonedTemplateProject.ProjectRootPath}\"\\file.ext", out string standardOutput, out string standardError)); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.ext"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -123,7 +124,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameExtension_SpecifyFramework _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, "file.ext"))); AssertCoverage(clonedTemplateProject, "file.ext"); } @@ -142,7 +143,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameWithDoubleExtension() _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.ext1.ext2"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -164,7 +165,7 @@ public void Test_MultipleTargetFrameworkReport_NoCoverletOutput() _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -191,7 +192,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -218,7 +219,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -248,7 +249,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -281,7 +282,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -307,7 +308,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { diff --git a/test/coverlet.integration.tests/coverlet.integration.tests.csproj b/test/coverlet.integration.tests/coverlet.integration.tests.csproj index 4c8cc9c50..fbb887bc2 100644 --- a/test/coverlet.integration.tests/coverlet.integration.tests.csproj +++ b/test/coverlet.integration.tests/coverlet.integration.tests.csproj @@ -29,6 +29,7 @@ +