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

Establish Code Coverage for WPF testing #10346

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,30 @@
<WpfArcadeSdkTargets>$(WpfArcadeSdkPath)Sdk\Sdk.targets</WpfArcadeSdkTargets>
</PropertyGroup>

<!-- For the purposes of generating code coverage as part of the build -->
<PropertyGroup Condition="'$(Coverage)' == 'true'">
<!-- Coverlet assumes PDB files exist on disk https://github.com/tonerdo/coverlet/issues/362 -->
<DebugType Condition="'$(DebugType)' == 'embedded'">portable</DebugType>
<!-- Coverlet's PDB check cannot handle deterministic source paths https://github.com/tonerdo/coverlet/issues/363 -->
<DeterministicSourcePaths>false</DeterministicSourcePaths>

<!-- Note: CoverletOutput references $(TargetDir) so it is set in Directory.Build.targets -->

<CollectCoverage>true</CollectCoverage>
<SingleHit>true</SingleHit> <!--see https://github.com/dotnet/machinelearning/pull/2843/files#r262544802-->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <!-- required due to https://github.com/tonerdo/coverlet/issues/72 -->
<CoverletOutputFormat>opencover</CoverletOutputFormat>
<Include>[System.Windows.*]*</Include>
<!-- Exclude only Obsolete and tagged with ExcludeFromCodeCoverage !!Avoid using this!! -->
<Exclude />
<ExcludeByAttribute>Obsolete,ExcludeFromCodeCoverage</ExcludeByAttribute>
<ExcludeByFile />
</PropertyGroup>

<!-- Make sure coverage targets are defined even in projects where coverlet is not installed -->
<Target Name="InstrumentModulesAfterBuild" />
<Target Name="GenerateCoverageResult" />

<Import Project="$(WpfArcadeSdkProps)"
Condition="Exists('$(WpfArcadeSdkProps)') And Exists('$(WpfArcadeSdkTargets)')"/>

Expand Down
12 changes: 12 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
<Project>
<!-- Set code coverage properties that reference properties not available in Directory.Build.props -->
<PropertyGroup Condition="'$(Coverage)' == 'true'">
<CoverletOutput>$(TargetDir)coverage\$(MSBuildProjectName).coverage</CoverletOutput>
</PropertyGroup>

<Target Name="InstrumentModulesNoBuildBeforeTest" Condition="'$(CollectCoverage)' == 'true'" BeforeTargets="RunTests">
<CallTarget Targets="InstrumentModulesAfterBuild" />
</Target>

<Target Name="GenerateCoverageResultAfterTest" Condition="'$(CollectCoverage)' == 'true'" AfterTargets="RunTests">
<CallTarget Targets="GenerateCoverageResult" />
</Target>

<Import Project="$(WpfArcadeSdkTargets)"
Condition="Exists('$(WpfArcadeSdkProps)') And Exists('$(WpfArcadeSdkTargets)')"/>

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Windows Presentation Foundation (WPF)
[![.NET Foundation](https://img.shields.io/badge/.NET%20Foundation-blueviolet.svg)](https://www.dotnetfoundation.org/)
[![Build Status](https://dnceng.visualstudio.com/public/_apis/build/status/dotnet/wpf/dotnet-wpf%20CI)](https://dnceng.visualstudio.com/public/_build/latest?definitionId=270)
[![codecov](https://codecov.io/gh/dotnet/wpf/branch/main/graph/badge.svg?flag=production)](https://codecov.io/gh/dotnet/wpf)
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/dotnet/wpf/blob/main/LICENSE.TXT)

Windows Presentation Foundation (WPF) is a UI framework for building Windows desktop applications.
Expand Down
35 changes: 35 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# https://docs.codecov.io/docs/codecov-yaml
# https://github.com/codecov/support/wiki/Codecov-Yaml

coverage:
range: 20..80 # 20 is red, 80 is green
round: down # always round down
precision: 5 # highest level of decimal precision
status:
project:
default: false
patch:
default: false
fixes:
- "eng/::/"

comment:
layout: "diff, flags" # coverage difference, flags below

flags: # which files to include in the reporting
production:
paths:
- src\Microsoft.DotNet.Wpf\src
- src\Microsoft.DotNet.Wpf\src\PresentationFramework
- src\Microsoft.DotNet.Wpf\src\PresentationCore
- src\Microsoft.DotNet.Wpf\src\PresentationUI
- src\Microsoft.DotNet.Wpf\src\ReachFramework
- src\Microsoft.DotNet.Wpf\src\System.Xaml
Comment on lines +23 to +27
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't necessary since they are just subsets of the line before it.

test:
paths:
- tests/
- src\Microsoft.DotNet.Wpf\tests\UnitTests\WindowsBase.Tests
- src\Microsoft.DotNet.Wpf\tests\UnitTests\PresentationCore.Tests
- src\Microsoft.DotNet.Wpf\tests\UnitTests\PresentationFramework.Fluent.Tests
- src\Microsoft.DotNet.Wpf\tests\UnitTests\System.Printing.Tests
- src\Microsoft.DotNet.Wpf\tests\UnitTests\System.Xaml.Tests
61 changes: 61 additions & 0 deletions eng/CodeCoverage.proj
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<Project Sdk="Microsoft.NET.Sdk" DefaultTargets="Codecov">

<PropertyGroup>
<!-- We need to specify a framework in order for the Restore target to work -->
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Codecov" Version="$(CodecovVersion)" />
<PackageReference Include="ReportGenerator" Version="$(ReportGeneratorVersion)" />
</ItemGroup>
<Target Name="Codecov" DependsOnTargets="Restore">
<PropertyGroup>
<_CodecovPath>$(NuGetPackageRoot)codecov\$(CodecovVersion)\tools\Codecov.exe</_CodecovPath>
<_ReportGeneratorPath>$(NuGetPackageRoot)reportgenerator\$(ReportGeneratorVersion)\tools\net47\ReportGenerator.exe</_ReportGeneratorPath>

<!-- The name of the source branch of the pull request. Ideally this would include the fork name, such as
'sharwell:coverage-cleanup', but only the branch name itself is available, such as 'coverage-cleanup'. -->
<_BranchName Condition="'$(_BranchName)' == ''">$(SYSTEM_PULLREQUEST_SOURCEBRANCH)</_BranchName>
<_BranchName Condition="'$(_BranchName)' == ''">$(BUILD_SOURCEBRANCHNAME)</_BranchName>
</PropertyGroup>

<ItemGroup>
<!-- [...\artifacts\bin\][project]\[configuration]\[framework]\coverage\[project].coverage-->
<_CoverageReports Include="$(ArtifactsBinDir)*\$(Configuration)\*\coverage\*.coverage" />
</ItemGroup>

<!-- Merge multiple coverlet reports into a single Cobertura report before uploading to codecov.io, in order to
reduce upload size and load on the codecov.io processing servers. -->
<Message Importance="high" Text="&quot;$(_ReportGeneratorPath)&quot; &quot;-reports:@(_CoverageReports)&quot; -targetdir:$(BaseOutputPath)coverage -reporttypes:Cobertura" />
<Exec Command="&quot;$(_ReportGeneratorPath)&quot; &quot;-reports:@(_CoverageReports)&quot; -targetdir:$(BaseOutputPath)coverage -reporttypes:Cobertura" />

<ItemGroup>
<!-- These are the best known interpretation of options defined in
https://github.com/codecov/codecov-exe/blob/master/Source/Codecov/Program/CommandLineOptions.cs -->
<_CodecovArgs Include="-f;$(BaseOutputPath)coverage\Cobertura.xml" />
<_CodecovArgs Include="-r;$(BUILD_REPOSITORY_NAME)" Condition="'$(BUILD_REPOSITORY_NAME)' != ''" />
<_CodecovArgs Include="--pr;$(SYSTEM_PULLREQUEST_PULLREQUESTNUMBER)" Condition="'$(SYSTEM_PULLREQUEST_PULLREQUESTNUMBER)' != ''" />
<_CodecovArgs Include="-b;$(BUILD_BUILDNUMBER)" Condition="'$(BUILD_BUILDNUMBER)' != ''" />
<_CodecovArgs Include="--branch;$(_BranchName)" Condition="'$(_BranchName)' != ''" />
<_CodecovArgs Include="-c;$(BUILD_SOURCEVERSION)" Condition="'$(BUILD_SOURCEVERSION)' != ''" />
<_CodecovArgs Include="-n;$(BUILD_DEFINITIONNAME)" Condition="'$(BUILD_DEFINITIONNAME)' != ''" />
<_CodecovArgs Include="-t;$(CodeCovToken)" Condition="'$(CodeCovToken)' != ''" />

<_CodecovFlags Include="$(Configuration)" Condition="'$(Configuration)' != ''" />
<_CodecovProductionFlags Include="@(_CodecovFlags)" />
<_CodecovProductionFlags Include="production" />
<_CodecovTestFlags Include="@(_CodecovFlags)" />
<_CodecovTestFlags Include="test" />
</ItemGroup>

<!-- Upload the coverage file with a 'production' flag, which will be filtered by codecov.io to production code -->
<Message Importance="high" Text="&quot;$(_CodecovPath)&quot; @(_CodecovArgs, ' ') --flag @(_CodecovProductionFlags, ',')" />
<Exec Command="&quot;$(_CodecovPath)&quot; @(_CodecovArgs, ' ') --flag @(_CodecovProductionFlags, ',')" />

<!-- Upload the coverage file with a 'test' flag, which will be filtered by codecov.io to test code -->
<Message Importance="high" Text="&quot;$(_CodecovPath)&quot; @(_CodecovArgs, ' ') --flag @(_CodecovTestFlags, ',')" />
<Exec Command="&quot;$(_CodecovPath)&quot; @(_CodecovArgs, ' ') --flag @(_CodecovTestFlags, ',')" />
</Target>

</Project>
14 changes: 13 additions & 1 deletion eng/pipeline-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,15 @@ jobs:
${{ if eq(parameters.runAsPublic, 'true') }}:
Build_Debug_x86:
_BuildConfig: Debug
_Coverage: true
# override some variables for debug
# _SignType has to be real for package publishing to succeed - do not override to test.
Build_Release_x86:
_BuildConfig: Release
${{ if eq(parameters.runAsPublic, 'true') }}:
Build_Debug_x64:
_BuildConfig: Debug
_Coverage: true
# override some variables for debug
# _SignType has to be real for package publishing to succeed - do not override to test.
_Platform: x64
Expand Down Expand Up @@ -174,6 +176,7 @@ jobs:
$(_OfficialBuildIdArgs)
$(_PlatformArgs)
$(_InternalRuntimeDownloadArgs)
/p:Coverage=$(_Coverage)
displayName: Windows Build / Publish
# This condition should be kept in sync with the condition for 'Run DRTs' step
# When building on a regular pipeline (!_HelixPipeline), build as usual
Expand All @@ -191,6 +194,7 @@ jobs:
$(_PlatformArgs)
$(_InternalRuntimeDownloadArgs)
/bl:$(Build.SourcesDirectory)\artifacts\log\$(_BuildConfig)\Test.binlog
/p:Coverage=$(_Coverage)
displayName: Run xUnit Tests
condition: and(or(ne(variables['_HelixPipeline'], 'true'), and(eq(variables['_HelixPipeline'], 'true') ,eq(variables['_BuildConfig'], 'Release'), eq(variables['_PublicBuildPipeline'], 'true'), eq(variables['_ContinuousIntegrationTestsEnabled'], 'true'))), ne(variables['_Platform'], 'arm64'))

Expand All @@ -203,7 +207,15 @@ jobs:
mergeTestResults: true
continueOnError: true
condition: and(eq(variables['_BuildConfig'], 'Release'), ne(variables['_Platform'], 'arm64'))


# Upload code coverage data
- script: $(Build.SourcesDirectory)/.dotnet/dotnet msbuild
eng/CodeCoverage.proj
/p:Configuration=$(_BuildConfig)
/p:CodeCovToken=$(CODECOV_TOKEN)
/bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\CodeCoverage.binlog
displayName: Upload coverage to codecov.io
condition: and(succeeded(), eq(variables._Coverage, 'true'))
# - task: PowerShell@2
# displayName: Install .NET Core
# inputs:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<PackageReference Include="xunit.stafact" Version="$(XUnitStaFactPackageVersion)" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerPackageVersion)" />
<PackageReference Include="$(SystemIOPackagingPackage)" Version="$(SystemIOPackagingVersion)" />
<PackageReference Include="coverlet.msbuild" Version="$(CoverletMSBuildPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<PackageReference Include="xunit.stafact" Version="$(XUnitStaFactPackageVersion)" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerPackageVersion)" />
<PackageReference Include="System.Private.Windows.Core.TestUtilities" Version="$(SystemPrivateWindowsCoreTestUtilitiesVersion)" />
<PackageReference Include="coverlet.msbuild" Version="$(CoverletMSBuildPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading