diff --git a/Directory.Build.props b/Directory.Build.props
index e186a4b28c7..70c0c1d3c2b 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -22,6 +22,30 @@
$(WpfArcadeSdkPath)Sdk\Sdk.targets
+
+
+
+ portable
+
+ false
+
+
+
+ true
+ true
+ true
+ opencover
+ [System.Windows.*]*
+
+
+ Obsolete,ExcludeFromCodeCoverage
+
+
+
+
+
+
+
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 224a9dbc152..7f908476f72 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,5 +1,17 @@
+
+
+ $(TargetDir)coverage\$(MSBuildProjectName).coverage
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index aef55f46d3d..734ee0089ac 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 00000000000..bfaae24a293
--- /dev/null
+++ b/codecov.yml
@@ -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
+ 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
diff --git a/eng/CodeCoverage.proj b/eng/CodeCoverage.proj
new file mode 100644
index 00000000000..1c2f2205f36
--- /dev/null
+++ b/eng/CodeCoverage.proj
@@ -0,0 +1,61 @@
+
+
+
+
+ netcoreapp3.0
+
+
+
+
+
+
+
+
+ <_CodecovPath>$(NuGetPackageRoot)codecov\$(CodecovVersion)\tools\Codecov.exe
+ <_ReportGeneratorPath>$(NuGetPackageRoot)reportgenerator\$(ReportGeneratorVersion)\tools\net47\ReportGenerator.exe
+
+
+ <_BranchName Condition="'$(_BranchName)' == ''">$(SYSTEM_PULLREQUEST_SOURCEBRANCH)
+ <_BranchName Condition="'$(_BranchName)' == ''">$(BUILD_SOURCEBRANCHNAME)
+
+
+
+
+ <_CoverageReports Include="$(ArtifactsBinDir)*\$(Configuration)\*\coverage\*.coverage" />
+
+
+
+
+
+
+
+
+ <_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" />
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/eng/pipeline-pr.yml b/eng/pipeline-pr.yml
index fe2fc86d383..cfc493c5b6e 100644
--- a/eng/pipeline-pr.yml
+++ b/eng/pipeline-pr.yml
@@ -132,6 +132,7 @@ 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:
@@ -139,6 +140,7 @@ jobs:
${{ 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
@@ -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
@@ -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'))
@@ -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:
diff --git a/src/Microsoft.DotNet.Wpf/tests/UnitTests/PresentationFramework.Fluent.Tests/PresentationFramework.Fluent.Tests.csproj b/src/Microsoft.DotNet.Wpf/tests/UnitTests/PresentationFramework.Fluent.Tests/PresentationFramework.Fluent.Tests.csproj
index 6a36f43d216..b4f5e788419 100644
--- a/src/Microsoft.DotNet.Wpf/tests/UnitTests/PresentationFramework.Fluent.Tests/PresentationFramework.Fluent.Tests.csproj
+++ b/src/Microsoft.DotNet.Wpf/tests/UnitTests/PresentationFramework.Fluent.Tests/PresentationFramework.Fluent.Tests.csproj
@@ -13,6 +13,7 @@
+
diff --git a/src/Microsoft.DotNet.Wpf/tests/UnitTests/System.Printing.Tests/System.Printing.Tests.csproj b/src/Microsoft.DotNet.Wpf/tests/UnitTests/System.Printing.Tests/System.Printing.Tests.csproj
index 967e81ca7df..0ab503e4f53 100644
--- a/src/Microsoft.DotNet.Wpf/tests/UnitTests/System.Printing.Tests/System.Printing.Tests.csproj
+++ b/src/Microsoft.DotNet.Wpf/tests/UnitTests/System.Printing.Tests/System.Printing.Tests.csproj
@@ -14,6 +14,7 @@
+