Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Branch coverage Issue - async await #1177

Closed
g0dm0d3 opened this issue Jun 8, 2021 · 2 comments · Fixed by #1201
Closed

Branch coverage Issue - async await #1177

g0dm0d3 opened this issue Jun 8, 2021 · 2 comments · Fixed by #1201
Assignees
Labels
bug Something isn't working tenet-coverage Issue related to possible incorrect coverage

Comments

@g0dm0d3
Copy link

g0dm0d3 commented Jun 8, 2021

Hi again)
Code:

namespace CoverletAsync
{
    public class MyService
    {
        public async Task<byte[]> GetBytes(Func<Task<bool>> process, Func<Task<MemoryStream>> getStream, Func<ISession> getSession, Func<Stream, ISession, Task<byte[]>> doWithStream)
        {
            if (!await process())
            {
                return Array.Empty<byte>();
            }

            using var session = getSession();
            await using var stream = await getStream();
            return await doWithStream(stream, session);
        }

        public interface ISession : IDisposable
        {
        }
    }
}

Test:

namespace CoverletAsync.Tests
{
    public class Tests
    {
        [Test]
        public async Task SomeMethodEmpty()
        {
            await using var memoryStream = new MemoryStream();
            var actual = await new MyService().GetBytes(() => Task.FromResult(false), () => Task.FromResult(memoryStream), () => new TestSession(), (stream, session) => Task.FromResult(new byte[] { 0x01, 0x02 }));

            CollectionAssert.IsEmpty(actual);
        }

        [Test]
        public async Task SomeMethodNonEmpty()
        {
            await using var memoryStream = new MemoryStream();
            var actual = await new MyService().GetBytes(() => Task.FromResult(true), () => Task.FromResult(memoryStream), () => new TestSession(), (stream, session) => Task.FromResult(new byte[] { 0x01, 0x02 }));

            Assert.That(actual, Is.EqualTo(new byte[] { 0x01, 0x02 }));
        }

        private class TestSession : MyService.ISession
        {
            public void Dispose()
            {
            }
        }
    }
}

Expected:
Full branch coverage

Actual:
Partially covered (1 visits, 2 of 4 branches are covered)

Output:
image

Report:

<?xml version="1.0" encoding="utf-8"?>
<coverage line-rate="1" branch-rate="0.75" version="1.9" timestamp="1623166089" lines-covered="8" lines-valid="8" branches-covered="6" branches-valid="8">
  <sources>
    <source>F:\</source>
  </sources>
  <packages>
    <package name="CoverletAsync" line-rate="1" branch-rate="0.75" complexity="8">
      <classes>
        <class name="CoverletAsync.MyService/&lt;GetBytes&gt;d__0" filename="Work\experiments\CoverletAsync\CoverletAsync\MyService.cs" line-rate="1" branch-rate="0.75" complexity="8">
          <methods>
            <method name="MoveNext" signature="()" line-rate="1" branch-rate="0.75" complexity="8">
              <lines>
                <line number="10" hits="2" branch="True" condition-coverage="100% (2/2)">
                  <conditions>
                    <condition number="16" type="jump" coverage="100%" />
                  </conditions>
                </line>
                <line number="11" hits="2" branch="True" condition-coverage="100% (2/2)">
                  <conditions>
                    <condition number="146" type="jump" coverage="100%" />
                  </conditions>
                </line>
                <line number="12" hits="1" branch="False" />
                <line number="13" hits="1" branch="False" />
                <line number="16" hits="1" branch="True" condition-coverage="50% (2/4)">
                  <conditions>
                    <condition number="181" type="switch" coverage="50%" />
                  </conditions>
                </line>
                <line number="17" hits="1" branch="False" />
                <line number="18" hits="1" branch="False" />
                <line number="19" hits="2" branch="False" />
              </lines>
            </method>
          </methods>
          <lines>
            <line number="10" hits="2" branch="True" condition-coverage="100% (2/2)">
              <conditions>
                <condition number="16" type="jump" coverage="100%" />
              </conditions>
            </line>
            <line number="11" hits="2" branch="True" condition-coverage="100% (2/2)">
              <conditions>
                <condition number="146" type="jump" coverage="100%" />
              </conditions>
            </line>
            <line number="12" hits="1" branch="False" />
            <line number="13" hits="1" branch="False" />
            <line number="16" hits="1" branch="True" condition-coverage="50% (2/4)">
              <conditions>
                <condition number="181" type="switch" coverage="50%" />
              </conditions>
            </line>
            <line number="17" hits="1" branch="False" />
            <line number="18" hits="1" branch="False" />
            <line number="19" hits="2" branch="False" />
          </lines>
        </class>
      </classes>
    </package>
  </packages>
</coverage>

Run: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura

Reproduced in .NET Core 3.1, Coverlet 3.0.3 / Coverlet 3.0.4-preview.31.g4902c245c8

@MarcoRossignoli MarcoRossignoli added tenet-coverage Issue related to possible incorrect coverage untriaged To be investigated labels Jun 21, 2021
@daveMueller
Copy link
Collaborator

Maybe a duplicate #1176.

@daveMueller daveMueller self-assigned this Jul 10, 2021
@daveMueller
Copy link
Collaborator

The IL switch isn't ignored when there is a code like this

await
xxx
await
await
await

image

I just took a quick peek and couldn't properly detect the pattern yet but I'm working on it. And I now can confirm that it is a duplicate to #1176.

@daveMueller daveMueller added bug Something isn't working and removed untriaged To be investigated labels Jul 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working tenet-coverage Issue related to possible incorrect coverage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants