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

[BUG] Code coverage empty on NET8.0 WPF project #1713

Open
modmynitro opened this issue Nov 27, 2024 · 7 comments
Open

[BUG] Code coverage empty on NET8.0 WPF project #1713

modmynitro opened this issue Nov 27, 2024 · 7 comments
Labels
bug Something isn't working documentation with repro Issue with repro

Comments

@modmynitro
Copy link

Describe the bug
Code Coverage on NET8.0 WPF project is empty.

To Reproduce
Create a .NET8 WPF project and refrence an enum value out of 'PresentationFramework' as default value.

public class Class
{
    public void Method(MessageBoxButton button = MessageBoxButton.OK)
    {
    }
}

Create a test project with an arbitrary test and run dotnet test --configuration Debug --collect:"XPlat Code Coverage".

Expected behavior
Code coverage should not be empty.

Actual behavior
The resulting coverage is empty.

When executing:
dotnet test .\TestProject.sln --configuration Debug --collect:"XPlat Code Coverage" --diag:log.txt

The log.datacollector.***.txt contains following exception:

Coverlet.Core.Exceptions.CecilAssemblyResolutionException: AssemblyResolutionException for 'PresentationFramework, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Try to add <PreserveCompilationContext>true</PreserveCompilationContext> to test projects </PropertyGroup> or pass '/p:CopyLocalLockFileAssemblies=true' option to the 'dotnet test' command-line
 ---> Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'PresentationFramework, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   --- End of inner exception stack trace ---
   at Coverlet.Core.Instrumentation.NetstandardAwareAssemblyResolver.TryWithCustomResolverOnDotNetCore(AssemblyNameReference name) in /_/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs:line 217
   at Coverlet.Core.Instrumentation.NetstandardAwareAssemblyResolver.Resolve(AssemblyNameReference name) in /_/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs:line 129
   at Mono.Cecil.MetadataResolver.Resolve(TypeReference type)
   at Mono.Cecil.ModuleDefinition.Resolve(TypeReference type)
   at Mono.Cecil.TypeReference.Resolve()
   at Mono.Cecil.Mixin.CheckedResolve(TypeReference self)
   at Mono.Cecil.MetadataBuilder.GetConstantType(TypeReference constant_type, Object constant)
   at Mono.Cecil.MetadataBuilder.AddConstant(IConstantProvider owner, TypeReference type)
   at Mono.Cecil.MetadataBuilder.AddParameter(UInt16 sequence, ParameterDefinition parameter, ParamTable table)
   at Mono.Cecil.MetadataBuilder.AddParameters(MethodDefinition method)
   at Mono.Cecil.MetadataBuilder.AddMethod(MethodDefinition method)
   at Mono.Cecil.MetadataBuilder.AddMethods(TypeDefinition type)
   at Mono.Cecil.MetadataBuilder.AddType(TypeDefinition type)
   at Mono.Cecil.MetadataBuilder.AddTypes()
   at Mono.Cecil.MetadataBuilder.BuildTypes()
   at Mono.Cecil.MetadataBuilder.BuildModule()
   at Mono.Cecil.MetadataBuilder.BuildMetadata()
   at Mono.Cecil.ModuleWriter.<>c.<BuildMetadata>b__2_0(MetadataBuilder builder, MetadataReader _)
   at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func`3 read)
   at Mono.Cecil.ModuleWriter.BuildMetadata(ModuleDefinition module, MetadataBuilder metadata)
   at Mono.Cecil.ModuleWriter.Write(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
   at Mono.Cecil.ModuleWriter.WriteModule(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
   at Mono.Cecil.ModuleDefinition.Write(Stream stream, WriterParameters parameters)
   at Coverlet.Core.Instrumentation.Instrumenter.InstrumentModule() in /_/src/coverlet.core/Instrumentation/Instrumenter.cs:line 325
   at Coverlet.Core.Instrumentation.Instrumenter.Instrument() in /_/src/coverlet.core/Instrumentation/Instrumenter.cs:line 148
   at Coverlet.Core.Coverage.PrepareModules() in /_/src/coverlet.core/Coverage.cs:line 134

Configuration (please complete the following information):
Please provide more information on your .NET configuration:
* Which coverlet package and version was used? => 6.0.2 also tested 6.0.3-preview.17.g302886a430
* Which version of .NET is the code running on? => net8.0-windows and net9.0-windows
* What OS and version, and what distro if applicable? => Microsoft Windows 10 Enterprise 19045
* What is the architecture (x64, x86, ARM, ARM64)? => x64
* Do you know whether it is specific to that configuration? => no

Additional context
Adding <PreserveCompilationContext>true</PreserveCompilationContext> did not help.
Adding /p:CopyLocalLockFileAssemblies=true did also not help.

❗ Please also read Known Issues

@github-actions github-actions bot added the untriaged To be investigated label Nov 27, 2024
@Bertk Bertk added the needs repro Needs repro to be investigated, cannot repro in local label Dec 7, 2024
@Bertk
Copy link
Collaborator

Bertk commented Dec 7, 2024

Please provide a repo for analysis. I not able to reproduce the exception.

@Bertk Bertk added the waiting for customer Waiting for customer action label Dec 7, 2024
@modmynitro
Copy link
Author

I have created a repo for this issue. https://github.com/modmynitro/coverlet-test

@Bertk Bertk added with repro Issue with repro and removed needs repro Needs repro to be investigated, cannot repro in local labels Dec 9, 2024
@Bertk
Copy link
Collaborator

Bertk commented Dec 10, 2024

Thank you for the repo. I updated the target framework and used net48 which solved the problem.

steps:

  • dotnet build
  • dotnet publish -c debug
  • dotnet test --configuration Debug --collect:"XPlat Code Coverage" --diag:log.txt

TestProject\TestProject.csproj

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net48</TargetFramework>
        <UseWpf>true</UseWpf>
        <LangVersion>10.0</LangVersion>
    </PropertyGroup>

</Project>

TestProjectTests\TestProjectTests.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <LangVersion>10.0</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\TestProject\TestProject.csproj"/>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="NUnit" Version="4.2.2"/>
    <PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
    <PackageReference Include="coverlet.collector" Version="6.0.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

</Project>

coverage.cobertura.xml

<?xml version="1.0" encoding="utf-8"?>
<coverage line-rate="1" branch-rate="1" version="1.9" timestamp="1733822473" lines-covered="2" lines-valid="2" branches-covered="0" branches-valid="0">
  <sources>
    <source>C:\</source>
  </sources>
  <packages>
    <package name="TestProject" line-rate="1" branch-rate="1" complexity="1">
      <classes>
        <class name="TestProject.Class" filename="GitHub\coverlet-issue-1713\TestProject\Class.cs" line-rate="1" branch-rate="1" complexity="1">
          <methods>
            <method name="Method" signature="(System.Windows.MessageBoxButton)" line-rate="1" branch-rate="1" complexity="1">
              <lines>
                <line number="8" hits="1" branch="False" />
                <line number="9" hits="1" branch="False" />
              </lines>
            </method>
          </methods>
          <lines>
            <line number="8" hits="1" branch="False" />
            <line number="9" hits="1" branch="False" />
          </lines>
        </class>
      </classes>
    </package>
  </packages>
</coverage>

@Bertk Bertk removed the untriaged To be investigated label Dec 10, 2024
@modmynitro
Copy link
Author

I want to use net8.0 not .NET Framework so this does not help in my situation.

@Bertk
Copy link
Collaborator

Bertk commented Dec 11, 2024

OK. I will investigate (debug) this issue in the next days.

@Bertk
Copy link
Collaborator

Bertk commented Dec 16, 2024

The test project targeting net8.0-windows need the property <SelfContained>true</SelfContained> which resolves the CecilAssemblyResolutionException.

Unfortunately this is not documented anywhere but a hint shall be added for coverlet.msbuild and coverlet.collector.

Solution:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <LangVersion>10.0</LangVersion>
    <PreserveCompilationContext>true</PreserveCompilationContext>
    <SelfContained>true</SelfContained>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\TestProject\TestProject.csproj"/>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="NUnit" Version="4.2.2"/>
    <PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
    <PackageReference Include="coverlet.collector" Version="6.0.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
    </PackageReference>
  </ItemGroup>

</Project>

Results:

C:\GitHub\coverlet-issue-1713>dotnet build
  Determining projects to restore...
  All projects are up-to-date for restore.
  TestProject -> C:\GitHub\coverlet-issue-1713\TestProject\bin\Debug\net8.0-windows\TestProject.dll
  wpf-template -> C:\GitHub\coverlet-issue-1713\wpf-template\bin\Debug\net8.0-windows\wpf-template.dll
  TestProjectTests -> C:\GitHub\coverlet-issue-1713\TestProjectTests\bin\Debug\net8.0-windows\win-x64\TestProjectTests.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:04.31

C:\GitHub\coverlet-issue-1713>dotnet test --configuration Debug --collect:"XPlat Code Coverage" --diag:log.txt
  Determining projects to restore...
  All projects are up-to-date for restore.
  TestProject -> C:\GitHub\coverlet-issue-1713\TestProject\bin\Debug\net8.0-windows\TestProject.dll
  TestProjectTests -> C:\GitHub\coverlet-issue-1713\TestProjectTests\bin\Debug\net8.0-windows\win-x64\TestProjectTests.dll
Test run for C:\GitHub\coverlet-issue-1713\TestProjectTests\bin\Debug\net8.0-windows\win-x64\TestProjectTests.dll (.NETCoreApp,Version=v8.0)
VSTest version 17.11.1-release-24455-02 (x64)

Starting test execution, please wait...
Logging Vstest Diagnostics in file: C:\GitHub\coverlet-issue-1713\log.txt
A total of 1 test files matched the specified pattern.

Passed!  - Failed:     0, Passed:     1, Skipped:     0, Total:     1, Duration: 6 ms - TestProjectTests.dll (net8.0)

Attachments:
  C:\GitHub\coverlet-issue-1713\TestProjectTests\TestResults\abf916bc-6eea-4b68-9a2f-7430eea846e1\coverage.cobertura.xml

C:\GitHub\coverlet-issue-1713>type C:\GitHub\coverlet-issue-1713\TestProjectTests\TestResults\abf916bc-6eea-4b68-9a2f-7430eea846e1\coverage.cobertura.xml
<?xml version="1.0" encoding="utf-8"?>
<coverage line-rate="1" branch-rate="1" version="1.9" timestamp="1734340041" lines-covered="2" lines-valid="2" branches-covered="0" branches-valid="0">
  <sources>
    <source>C:\</source>
  </sources>
  <packages>
    <package name="TestProject" line-rate="1" branch-rate="1" complexity="1">
      <classes>
        <class name="TestProject.Class" filename="GitHub\coverlet-issue-1713\TestProject\Class.cs" line-rate="1" branch-rate="1" complexity="1">
          <methods>
            <method name="Method" signature="(System.Windows.MessageBoxButton)" line-rate="1" branch-rate="1" complexity="1">
              <lines>
                <line number="11" hits="1" branch="False" />
                <line number="12" hits="1" branch="False" />
              </lines>
            </method>
          </methods>
          <lines>
            <line number="11" hits="1" branch="False" />
            <line number="12" hits="1" branch="False" />
          </lines>
        </class>
      </classes>
    </package>
  </packages>
</coverage>
C:\GitHub\coverlet-issue-1713>

@Bertk Bertk added bug Something isn't working documentation labels Dec 16, 2024
@modmynitro
Copy link
Author

I can use this solution as workaround, but we only use dotnet test on our gitlab runners and this solution forces any local build to be self contained.

I would expect the runtime assemblies to be found automatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working documentation with repro Issue with repro
Projects
None yet
Development

No branches or pull requests

2 participants