coverlet-coverage / coverlet

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

ExcludeFromCodeCoverage skipped for some lines in excluded method #1072

Open kinder001 opened 3 years ago

kinder001 commented 3 years ago

Hello! I use coverlet NuGet version 3.0.2

I have method marked as [ExcludeFromCodeCoverage], It's async method. Some lines inside method skipped from excluding and are marked as uncovered, It's on PrintScreen from report below code

`` [ExcludeFromCodeCoverage] public async Task<List> GetOrganizationStructureByPartnerAsync(Guid partnerId) { var topPartner = await _partnerService.GetTopPartnerAsync(partnerId);

        var filials = await GetFilialsByBusinessUnits().Where(i=>i.NewDicFilialExtensionBase.NewPartnerId == topPartner.Id)
                                                       .ToListAsync();

        var filialIds = filials.Select(i => i.NewDicFilialId).ToList();

        var businessUnits = await _db.BusinessUnitBase.Include(i => i.BusinessUnitExtensionBase)
                                                      .In(filialIds, i=> i.BusinessUnitExtensionBase.NewFilialid.Value)
                                                      .ToListAsync();

        return filials.Select(i => i.ToViewModel(businessUnits)).ToList();
    }

``

And printscreen from coverage report

Снимок экрана 2021-01-27 в 13 35 38
MarcoRossignoli commented 3 years ago

Thanks for reporting this.

@matteoerigozzi, regression?

Svmurvj commented 3 years ago

We start using version 3.0.3 few days ago and we face same issue. Any news when that will be resolved, or workaround ?

image

Previously we were using those versions:

    <PackageReference Include="coverlet.collector" Version="1.3.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="coverlet.msbuild" Version="2.9.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
    </PackageReference>

and everything worked well.

Additional - here is our piece of pipeline execution - if that matter:


    - task: SonarCloudPrepare@1
      displayName: "Prepare analysis on SonarCloud"
      inputs:
        SonarCloud: X
        organization: X
        projectKey: "$(SonarProjectName)"
        projectName: "$(SonarCloudProjectName)"
        projectVersion: $(version)
        extraProperties: |
          sonar.inclusions=src/**/$(ProjectName)/**/*
          sonar.cs.opencover.reportsPaths=$(Build.SourcesDirectory)/**/coverage.opencover.xml

    - task: UseDotNet@2
      displayName: "Install .net core 3.1"
      inputs:
        version: "3.1.x"

    - task: DotNetCoreCLI@2
      displayName: "Install dotnet-reportgenerator-globaltool"
      inputs:
        command: custom
        custom: tool
        arguments: "install --global dotnet-reportgenerator-globaltool --ignore-failed-sources"

    - task: DotNetCoreCLI@2
      displayName: Build
      inputs:
        command: "restore"
        projects: "$(Solution)"
        feedsToUse: "config"
        nugetConfigPath: "nuget.config"
        arguments: " --runtime $(BuildRuntime)"

    - task: DotNetCoreCLI@2
      displayName: "Test solution"
      inputs:
        command: "test"
        projects: "**/*$(ProjectName).*Test*(s).csproj"
        arguments: '--configuration $(BuildConfiguration) --logger "trx" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[*.Tests]*" /p:ExcludeByAttribute=Obsolete /p:ExcludeByAttribute=ObsoleteAttribute /p:ExcludeByAttribute=GeneratedCodeAttribute /p:ExcludeByAttribute=CompilerGeneratedAttribute /p:ExcludeByAttribute=ExcludeFromCodeCoverage /p:ExcludeByAttribute=ExcludeFromCodeCoverageAttribute'
        nobuild: true

    - script: |
        reportgenerator "-reports:$(Build.SourcesDirectory)/**/coverage.opencover.xml" "-targetDir:$(Build.SourcesDirectory)/**/coverage.opencover.xml" -tag:$(Build.BuildNumber) "-reporttypes:Cobertura;HTMLInline;HTMLChart"
      displayName: Create Code coverage report

    - task: PublishCodeCoverageResults@1
      displayName: "Publish code coverage"
      inputs:
        codeCoverageTool: Cobertura
        summaryFileLocation: $(Build.SourcesDirectory)/**/coverage.opencover.xml/Cobertura.xml
        reportDirectory: $(Build.SourcesDirectory)/**/coverage.opencover.xml
        failIfCoverageEmpty: false

    - task: SonarCloudAnalyze@1

    - task: SonarCloudPublish@1
      inputs:
        pollingTimeoutSec: "300"
daveMueller commented 3 years ago

Thanks for reporting this. I looked into it today but couldn't reproduce it. Could you provide a small repro?

Olegone23 commented 2 years ago

Had same issue: coverlet console version: v3.1.0 cake.coverlet: v2.5.4 Added cake settings: ExcludeByAttribute = new List(){"ObsoleteAttribute","ExcludeFromCodeCoverageAttribute"}

But seems it does not work. issues_with_coverlet The lines marked as [ExcludeFromCodeCoverage], (Records) should not be analysed by sonar, but it did.

MarcoRossignoli commented 2 years ago

Hi all here,

at the moment coverlet try to follow the chain of caller(parent classes) in case [ExludeFromCodeCoverage] and also in my local test I'm not able to repro, looks like compiler does something new(organize types in a different way) and we need a simple repro to be able to fix this issue. You can find sample here https://github.com/coverlet-coverage/coverlet/tree/master/test/coverlet.core.tests/Samples ExcludeFromCoverage.IssueXXX

StingyJack commented 2 years ago

@MarcoRossignoli - Does this work for an example?

In this code, the GetClaimTypeValue function has all statements being reported as uncovered. The GetClaimValue that is below it is properly excluded from the analysis.

       /// <summary>
        ///     Gets the value of given claim type available in the httpcontext
        /// </summary>
        /// <param name="httpContextAccessor"></param>
        /// <param name="claimType"></param>
        /// <returns></returns>
        [ExcludeFromCodeCoverage] 
        public static string GetClaimTypeValue(this IHttpContextAccessor httpContextAccessor, string claimType)
        {
            if (httpContextAccessor == null)
            {
                throw new ArgumentNullException(nameof(httpContextAccessor));
            }

            var claims = httpContextAccessor.HttpContext?.User?.Claims?.ToList();
            return claims.GetClaimValue(claimType);
        }

        /// <summary>
        ///     To get the value of given type from the list of claims
        /// </summary>
        /// <param name="claims"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        [ExcludeFromCodeCoverage] 
        public static string GetClaimValue(this List<Claim> claims, string type)
        {
            if (claims == null)
            {
                return null;
            }

            var claimTypeValue = claims.Where(claim => claim.Type.Equals(type, StringComparison.OrdinalIgnoreCase)).Select(c => c.Value).FirstOrDefault();

            return string.IsNullOrWhiteSpace(claimTypeValue) ? null : claimTypeValue;
        }
Bertk commented 20 minutes ago

@kinder001 Could you please drop a comment whether this is still an issue.

Please use the latest version of coverlet.collector

[!TIP] Please use coverlet.collector or coverlet.msbuild in csproj and not both drivers. Recommended: coverlet.collector vstest integration.