Skip to content

Coverage of async methods #966

@danielpalme

Description

@danielpalme

I found a case where coverage of an async method is wrong.
I created a minimal repro using coverlet.collector 1.3.0.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SomeAssembly
{
    public class ClassUnderTest
    {
        public async Task Execute()
        {
            await this.ExcecuteInner();
        }

        private async Task ExcecuteInner()
        {
            Console.WriteLine("This line should get executed");
            var someClasses = new List<SomeClass>();

            if (someClasses.Count > 0 && !someClasses[0].SomeText.Any(x => x == 'x'))
            {
                Console.WriteLine("Hello");
            }
        }

        private class SomeClass
        {
            public string SomeText { get; set; }
        }
    }
}

The method ExcecuteInner() gets executed, but only the if statements shows up in coverage results, the other lines are missing:
image

If I simplify the if statement or make the method synchronous, the problem disappears.

The cobertura file does only contain information about the line with the if statement:

        <class name="SomeAssembly.ClassUnderTest/&lt;Execute&gt;d__0" filename="temp\SomeAssembly\ClassUnderTest.cs" line-rate="1" branch-rate="1" complexity="1">
          <methods>
            <method name="MoveNext" signature="()" line-rate="1" branch-rate="1" complexity="1">
              <lines>
                <line number="11" hits="1" branch="False" />
                <line number="12" hits="1" branch="False" />
                <line number="13" hits="1" branch="False" />
              </lines>
            </method>
          </methods>
          <lines>
            <line number="11" hits="1" branch="False" />
            <line number="12" hits="1" branch="False" />
            <line number="13" hits="1" branch="False" />
          </lines>
        </class>
        <class name="SomeAssembly.ClassUnderTest/&lt;&gt;c" filename="temp\SomeAssembly\ClassUnderTest.cs" line-rate="0" branch-rate="0.5" complexity="4">
          <methods>
            <method name="&lt;ExcecuteInner&gt;b__1_0" signature="(System.Char)" line-rate="0" branch-rate="0.5" complexity="4">
              <lines>
                <line number="20" hits="0" branch="True" condition-coverage="50% (2/4)">
                  <conditions>
                    <condition number="42" type="jump" coverage="50%" />
                    <condition number="105" type="jump" coverage="50%" />
                  </conditions>
                </line>
              </lines>
            </method>
          </methods>
          <lines>
            <line number="20" hits="0" branch="True" condition-coverage="50% (2/4)">
              <conditions>
                <condition number="42" type="jump" coverage="50%" />
                <condition number="105" type="jump" coverage="50%" />
              </conditions>
            </line>
          </lines>
        </class>

Here's a full project to reproduce the issue:
SampleProject.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions