coverlet-coverage / coverlet

Cross platform code coverage for .NET
MIT License
2.93k stars 386 forks source link

[BUG] ExcludeFromCodeCoverage does code exclude method in a partial class that contains a linq expression #1548

Closed bdurrani closed 7 months ago

bdurrani commented 8 months ago

Describe the bug Please share a clear and concise description of the problem.

To Reproduce I have the following class under Test

public partial class StuffMcStuffy
{
    private readonly ILogger<StuffMcStuffy> _logger;

    public StuffMcStuffy(ILogger<StuffMcStuffy> logger)
    {
        _logger = logger;
    }

    [LoggerMessage(
        EventId = 0,
        Level = LogLevel.Information,
        EventName = "testname",
        Message = "tes:extraction {JobId} {ExtractionStatus} {ExtractionError}")]
    private partial void RecordExtractionEvent(Guid jobId, string extractionStatus, string extractionError);

    [ExcludeFromCodeCoverage]
    public void DoThis()
    {
        Console.Write("do this");
    }

    public void DoThat()
    {
        Console.Write("do that");
    }

    public void BlahThis()
    {
        var thislist = new List<KeyValuePair<string, object>>();
        thislist.Add(new KeyValuePair<string, object>("hey", "ho"));
        thislist.Add(new KeyValuePair<string, object>("hey1", "ho1"));
        var blah = CreateLoggerDictionary(thislist);
        blah.ToString();
    }

    [ExcludeFromCodeCoverage]
    private static Dictionary<string, string> CreateLoggerDictionary(List<KeyValuePair<string, object>> attributes)
    {
        return attributes.ToDictionary(item => item.Key,
            item => item.Value.ToString() ?? string.Empty);
    }
}

I used the following script to run the unit tests and generate the coverage reports

#!/usr/bin/env bash

set -euo pipefail

find . -type d -name TestResults -exec rm -rf {} +
rm -rf ./codeCoverageReport

PROJECTS="$(find . -type d -name "TestProject1")"
readonly PROJECTS

for project in ${PROJECTS}; do
  dotnet test -c Release "$@" "${project}" --collect:"XPlat Code Coverage" --logger "console;verbosity=normal" --logger trx
done

dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
REPORT_TYPE=Html
COMMAND=open
FILENAME=index.html
TARGETDIRECTORY="$(ls -d "${dir}"/.)/codeCoverageReport"
REPORTS="$(find "${dir}/.." -type f -name "coverage.cobertura.xml" | tr "\n" ";")"

dotnet ~/.nuget/packages/reportgenerator/*/tools/*/ReportGenerator.dll \
  -reports:"${REPORTS}" \
  -targetdir:"${TARGETDIRECTORY}" \
  -reporttypes:"${REPORT_TYPE}" && \
  "${COMMAND}" "${TARGETDIRECTORY}/${FILENAME}"

Expected behavior

The method CreateLoggerDictionary() should be excluded from test coverage

Actual behavior

The method is not excluded from coverage

image

Workaround

Rewrite the code using foreach()

  private static Dictionary<string, string> CreateLoggerDictionary(List<KeyValuePair<string, object>> attributes)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        foreach (var attribute in attributes)
        {
            dictionary.Add(attribute.Key, attribute.Value.ToString() ?? string.Empty);
        }
        return dictionary;
    }
image

Configuration (please complete the following information): Please provide more information on your .NET configuration:

Additional context I've attached the project here Coverlet-Test.zip

:exclamation: Please also read Known Issues

Kralizek commented 8 months ago

I'm having the same issue

image
daveMueller commented 7 months ago

Thansk for reporting and thanks a lot for the repro 🙏. I just checked it and this will be fixed with PR https://github.com/coverlet-coverage/coverlet/pull/1542.

grafik

Kralizek commented 7 months ago

That was fast! thanks @daveMueller