Add --enable-coverage flag for code coverage collection from device tests#1565
Open
amirvenus wants to merge 4 commits intodotnet:mainfrom
Open
Add --enable-coverage flag for code coverage collection from device tests#1565amirvenus wants to merge 4 commits intodotnet:mainfrom
amirvenus wants to merge 4 commits intodotnet:mainfrom
Conversation
…ests Adds optional `--enable-coverage` CLI flag across all platforms (Android, Apple/iOS/tvOS, WASM) that enables code coverage collection during test execution. When enabled, XHarness coordinates coverage output paths and transports the resulting Cobertura XML files from the device back to the host output directory alongside test results. Changes: - New `--enable-coverage` switch argument shared across all platforms - `NUNIT_ENABLE_COVERAGE` / `NUNIT_COVERAGE_OUTPUT_PATH` env var support in ApplicationOptions for test runner configuration - CoverageManager that generates method-level Cobertura XML via reflection when no external coverage tool (coverlet) produces a file - Android: coverage flag passed as instrumentation arg, InstrumentationRunner pulls coverage-results-path from device via adb - Apple: coverage env vars injected into app environment for simulator/device - WASM: coverage data decoded from STARTCOVERAGEXML stdout markers - ThreadlessXunitTestRunner made public (enables Android apps to use the runner that works with assembly store, required for device testing) - Unit tests for CoverageManager Closes dotnet#1135
CoverageManager generates coverage via reflection — no external tool required. Standard tools like coverlet.msbuild cannot instrument assemblies for device builds (APK/app bundles) since they only hook into the dotnet test pipeline.
Author
|
The 2 failing checks ( All 12 checks relevant to our changes pass: builds (Windows/OSX, Debug/Release), Android E2E (devices, simulators, manual commands), Apple E2E (simulators, simulator commands, device commands), and WASM E2E. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an optional
--enable-coverageCLI flag across all platforms that enables code coverage collection during XHarness device test execution. When enabled, XHarness generates a Cobertura XML coverage report and places it in the output directory alongside test results.No external coverage tools (coverlet, etc.) are required. CoverageManager generates method-level coverage by reflecting over the loaded test assemblies. Standard tools like
coverlet.msbuildcannot instrument assemblies for device builds (APK/app bundles) since they only hook into thedotnet testpipeline — CoverageManager solves this by providing built-in coverage that works on all platforms.If an external tool has already produced a coverage file at the expected path, CoverageManager uses that file instead.
Addresses #1135.
What's included
--enable-coverageCLI flag on all platform commands:android test,android runapple test,apple just-testwasm test,wasm test-browserTest Runner integration (
TestRunners.Common):NUNIT_ENABLE_COVERAGE/NUNIT_COVERAGE_OUTPUT_PATHenvironment variable support inApplicationOptionsCoverageManagerthat generates method-level Cobertura XML via reflection over loaded test assemblies (no external dependencies)ApplicationEntryPoint.InternalRunAsync()Per-platform transport:
CoverageManagergenerates report → path reported viaINSTRUMENTATION_RESULT: coverage-results-path=<path>→InstrumentationRunnerpulls file from device viaadbNUNIT_ENABLE_COVERAGEinjected as env var via the orchestrator → coverage file written to app's Documents directory → pulled alongside test resultsSTARTCOVERAGEXML <len> <base64> ENDCOVERAGEXMLmarkers →WasmTestMessagesProcessordecodes and writes to output directoryThreadlessXunitTestRunnermade public: Enables Android test apps to use the runner that works with .NET Android's assembly store (in-memory test discovery viaReflectionAssemblyInfo, no.dllfile on disk required)Usage
After the run,
coverage.cobertura.xmlappears in the output directory. The file uses standard Cobertura format consumable by Azure DevOps, Codecov, ReportGenerator, etc.Test plan
CoverageManager(8 tests) — constructor, path resolution, env var setting, reflection coverage generation, fallback behaviorAndroid.OS.BuildAPI tests → deployed to emulator via locally-built XHarness CLI with--enable-coverage→ 5/5 tests passed →coverage.cobertura.xml(2,741 bytes) pulled from device to output directoryUIKit.UIDeviceAPI tests → ran on iPhone 11 Pro simulator (iOS 26.2) via locally-built XHarness CLI with--enable-coverage→ 6/6 tests passed →coverage.cobertura.xmlgenerated in app container🤖 Generated with Claude Code