coverlet icon indicating copy to clipboard operation
coverlet copied to clipboard

Bug: Excluded method is still included in the coverage report

Open extesy opened this issue 2 years ago • 11 comments

I think there is a regression from https://github.com/coverlet-coverage/coverlet/pull/849 bug fix. We are using coverlet 3.1.2 running on .net 6. There is a method declared like this:

    [ExcludeFromCodeCoverage]
    internal virtual async Task<RedisValue[]> DoRedisExecuteAsync(IRedisClient redisClient, string scriptContents, RedisKey redisKey, long exclusiveUpperBound)
    {
        var result = await redisClient.ExecuteAsync(async database =>
            await database.ScriptEvaluateAsync(scriptContents, keys: new[] { redisKey }, values: new RedisValue[] { exclusiveUpperBound })!
        )!;
        return (RedisValue[])result;
    }

When running unit tests and collecting coverage report, this method is still included in the report. Here is the relevant portion of the coverage report in different formats:

        <class name="CollectiblesItemService.SerialExecutor.DataLayer.RedisSerialCounterRepository/&lt;&gt;c__DisplayClass10_0/&lt;&lt;DoRedisExecuteAsync&gt;b__0&gt;d" filename="services/collectibles-item-service/src/SerialExecutor/DataLayer/SerialCounter/RedisSerialCounterRepository.cs" line-rate="0" branch-rate="1" complexity="1">
          <methods>
            <method name="MoveNext" signature="()" line-rate="0" branch-rate="1" complexity="1">
              <lines>
                <line number="167" hits="0" branch="False" />
              </lines>
            </method>
          </methods>
          <lines>
            <line number="167" hits="0" branch="False" />
          </lines>
        </class>
FN:166,System.Void CollectiblesItemService.SerialExecutor.DataLayer.RedisSerialCounterRepository/<>c__DisplayClass10_0/<<DoRedisExecuteAsync>b__0>d::MoveNext()
FNDA:0,System.Void CollectiblesItemService.SerialExecutor.DataLayer.RedisSerialCounterRepository/<>c__DisplayClass10_0/<<DoRedisExecuteAsync>b__0>d::MoveNext()
DA:167,0

Line 167 is the await database.ScriptEvaluateAsync line from that method. Somehow that single line is declared as "not covered" instead of being excluded with the rest of the method.

It might have something to do with this line being async lambda which complies into a more complicated state machine.

extesy avatar Oct 07 '22 20:10 extesy

Thanks for reporting this.

daveMueller avatar Oct 07 '22 22:10 daveMueller

Found a relevant stackoverflow: https://stackoverflow.com/questions/72487078/c-sharp-exclude-lambda-expression-from-code-coverage/72487708#72487708. Seems like coverlet is unable to trace the lambda function back to the function that contains it.

extesy avatar Oct 10 '22 22:10 extesy

You are right it seems so. I thought we have an algorithem for that but I also could be wrong. At least those two issues somehow seem to be related. https://github.com/coverlet-coverage/coverlet/issues/1302, https://github.com/coverlet-coverage/coverlet/issues/129.

daveMueller avatar Nov 26 '22 23:11 daveMueller

@daveMueller What does waiting for customer label mean? Do you need me to provide some extra information?

extesy avatar Nov 27 '22 06:11 extesy

Ohh sorry for that. I most likely fell asleep before I could hit the comment button yesterday 🙈 . I tried to reproduce this yesterday but wasn't able to.

grafik

Could you try to create a simple repro for that issue?

daveMueller avatar Nov 27 '22 21:11 daveMueller

I now also tried the code from the stackoverflow issue you referenced. But I'm also not able to reproduce this.

grafik

daveMueller avatar Nov 27 '22 21:11 daveMueller

Seeing the same issue on Coverlet 3.1.0 on .NET 6

image

Haven't tried updating, so could this be something that has since been patched in 3.2.0 maybe?

Nodnarb3 avatar Nov 29 '22 20:11 Nodnarb3

@Nodnarb3 I don't really think so. At least I can't remember a bugfix for an issue like that in the last release. Could you tell me how you build the assemblies under test? Do you maybe have a release build configuration?

daveMueller avatar Dec 02 '22 22:12 daveMueller

Projects are being built as follows, with BuildConfiguration set to debug:

...
  # Build all projects and don't allow warnings
  - task: DotNetCoreCLI@2
    displayName: 'dotnet build'
    inputs:
      command: build
      projects: '**/*.csproj'
      arguments: '/warnaserror --configuration $(BuildConfiguration)'

  # Test all projects and collect coverage results
  - task: DotNetCoreCLI@2
    displayName: 'dotnet test'
    inputs:
      command: 'test'
      projects: '${{ parameters.testGlob }}'
      arguments: '--configuration $(BuildConfiguration) --settings ./server/coverlet.runsettings --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura'
...

coverlet.runsettings:

<?xml version="1.0" encoding="utf-8"?>
<!-- File name extension must be .runsettings -->
<RunSettings>
	<DataCollectionRunSettings>
		<DataCollectors>
			<DataCollector friendlyName="XPlat Code Coverage">
				<Configuration>
                    <ExcludeByFile>**/Migrations/*.cs</ExcludeByFile>
                    <SingleHit>True</SingleHit>
				</Configuration>
			</DataCollector>
		</DataCollectors>
	</DataCollectionRunSettings>
</RunSettings>

Nodnarb3 avatar Dec 05 '22 17:12 Nodnarb3

Thanks @Nodnarb3, nothing really out of the ordinary. Unfortunately I still can't reproduce it. We would really appreciate if someone who has this issue could try to provide a simple repro. But don't feel obligated this is still open source.

daveMueller avatar Dec 06 '22 21:12 daveMueller

This issue is stale because it has been open for 3 months with no activity.

github-actions[bot] avatar Sep 03 '23 01:09 github-actions[bot]

This issue was closed because it has been inactive for 9 months since being marked as stale.

github-actions[bot] avatar Jun 09 '24 01:06 github-actions[bot]