From 362e353e43d84646fd553e1e85198431e1613b86 Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Tue, 18 Aug 2026 11:38:15 +0200 Subject: [PATCH] (test): migrate to xunit.v3 4.0 and microsoft testing platform --- CHANGELOG.md | 5 ++++ README.md | 6 ++-- .../MaksIT.HAMode.Tests.csproj | 14 +++------ src/MaksIT.HAMode/MaksIT.HAMode.csproj | 2 +- src/global.json | 5 ++++ utils/modules/TestRunner.psm1 | 30 +++++++++++++++---- utils/plugins/DotNet/DotNetTest.psm1 | 5 +++- 7 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 src/global.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 046a2d0..0738cf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.8] - 2026-08-18 + +### Changed +- Migrated tests to xunit.v3 `4.0` and Microsoft Testing Platform only (`src/global.json` `test.runner` next to the `.slnx`; no VSTest, `coverlet.collector`, `Microsoft.NET.Test.Sdk`, or `xunit.runner.visualstudio`). Coverage now uses `coverlet.MTP`; TestRunner always passes `--coverlet` scoped to `[MaksIT.*]*`. + ## [1.0.7] - 2026-08-14 ### Changed diff --git a/README.md b/README.md index d68a466..48590d6 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ Reusable high-availability runtime coordination library for MaksIT services. -![Line Coverage](https://img.shields.io/badge/Line%20Coverage-57.1%25-yellowgreen) -![Branch Coverage](https://img.shields.io/badge/Branch%20Coverage-49.1%25-yellowgreen) -![Method Coverage](https://img.shields.io/badge/Method%20Coverage-70.7%25-green) +![Line Coverage](https://img.shields.io/badge/Line%20Coverage-57%25-yellowgreen) +![Branch Coverage](https://img.shields.io/badge/Branch%20Coverage-50.9%25-yellowgreen) +![Method Coverage](https://img.shields.io/badge/Method%20Coverage-69.6%25-green) ## Packages diff --git a/src/MaksIT.HAMode.Tests/MaksIT.HAMode.Tests.csproj b/src/MaksIT.HAMode.Tests/MaksIT.HAMode.Tests.csproj index b8341f5..58ffeed 100644 --- a/src/MaksIT.HAMode.Tests/MaksIT.HAMode.Tests.csproj +++ b/src/MaksIT.HAMode.Tests/MaksIT.HAMode.Tests.csproj @@ -6,21 +6,15 @@ enable false true + Exe + true - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + diff --git a/src/MaksIT.HAMode/MaksIT.HAMode.csproj b/src/MaksIT.HAMode/MaksIT.HAMode.csproj index e0e81a3..b8368fe 100644 --- a/src/MaksIT.HAMode/MaksIT.HAMode.csproj +++ b/src/MaksIT.HAMode/MaksIT.HAMode.csproj @@ -8,7 +8,7 @@ $(NoWarn);CS1591 MaksIT.HAMode - 1.0.7 + 1.0.8 Maksym Sadovnychyy MAKS-IT MaksIT.HAMode diff --git a/src/global.json b/src/global.json new file mode 100644 index 0000000..3140116 --- /dev/null +++ b/src/global.json @@ -0,0 +1,5 @@ +{ + "test": { + "runner": "Microsoft.Testing.Platform" + } +} diff --git a/utils/modules/TestRunner.psm1 b/utils/modules/TestRunner.psm1 index aac3308..d1e2eea 100644 --- a/utils/modules/TestRunner.psm1 +++ b/utils/modules/TestRunner.psm1 @@ -7,7 +7,7 @@ .DESCRIPTION Provides the Invoke-TestsWithCoverage function for running .NET tests - with Coverlet code coverage collection and parsing results. + with Microsoft.Testing.Platform and coverlet.MTP code coverage. .NOTES Author: MaksIT @@ -65,6 +65,20 @@ function Write-TestRunnerLogInternal { Write-Host $Message -ForegroundColor Gray } +function Get-CoberturaCoverageFiles { + param( + [Parameter(Mandatory = $true)] + [string]$ResultsDirectory + ) + + # coverlet.MTP: [prefix.]coverage.cobertura[.timestamp].xml + $files = @( + Get-ChildItem -Path $ResultsDirectory -Recurse -File -ErrorAction SilentlyContinue | + Where-Object { $_.Name -like '*coverage.cobertura*.xml' } + ) + return @($files | Sort-Object FullName -Unique) +} + function Invoke-TestsWithCoverage { <# .SYNOPSIS @@ -155,7 +169,7 @@ function Invoke-TestsWithCoverage { New-Item -ItemType Directory -Path $ResultsDir -Force | Out-Null if (-not $Silent) { - Write-TestRunnerLogInternal -Level "STEP" -Message "Running tests with code coverage..." + Write-TestRunnerLogInternal -Level "STEP" -Message "Running tests with code coverage (Microsoft.Testing.Platform / coverlet.MTP)..." foreach ($d in $resolvedProjectDirs) { Write-TestRunnerLogInternal -Level "INFO" -Message "Test Project: $d" } @@ -164,11 +178,15 @@ function Invoke-TestsWithCoverage { foreach ($TestProjectDir in $resolvedProjectDirs) { Push-Location $TestProjectDir try { + $projectName = [System.IO.Path]::GetFileName($TestProjectDir) $dotnetArgs = @( "test" - "--collect:XPlat Code Coverage" "--results-directory", $ResultsDir "--verbosity", $(if ($Silent) { "quiet" } else { "normal" }) + "--coverlet" + "--coverlet-output-format", "cobertura" + "--coverlet-file-prefix", $projectName + "--coverlet-include", "[MaksIT.*]*" ) Import-ExternalCommandSupportInternal @@ -192,7 +210,7 @@ function Invoke-TestsWithCoverage { } } - $coverageFiles = @(Get-ChildItem -Path $ResultsDir -Filter "coverage.cobertura.xml" -Recurse | Sort-Object FullName) + $coverageFiles = @(Get-CoberturaCoverageFiles -ResultsDirectory $ResultsDir) if ($coverageFiles.Count -eq 0) { return [PSCustomObject]@{ @@ -455,7 +473,7 @@ function Get-DotNetCoverageFromResultsDirectory { [switch]$Silent ) - $coverageFiles = @(Get-ChildItem -Path $ResultsDirectory -Filter 'coverage.cobertura.xml' -Recurse -ErrorAction SilentlyContinue | Sort-Object FullName) + $coverageFiles = @(Get-CoberturaCoverageFiles -ResultsDirectory $ResultsDirectory) if ($coverageFiles.Count -eq 0) { return [PSCustomObject]@{ Success = $false @@ -566,7 +584,7 @@ function Get-CoverageFromResultsDirectory { } } - $hasDotNet = @(Get-ChildItem -Path $resolvedDirectory -Filter 'coverage.cobertura.xml' -Recurse -ErrorAction SilentlyContinue).Count -gt 0 + $hasDotNet = @(Get-CoberturaCoverageFiles -ResultsDirectory $resolvedDirectory).Count -gt 0 $jestSummary = Join-Path $resolvedDirectory 'coverage-summary.json' $hasNpm = Test-Path -LiteralPath $jestSummary -PathType Leaf diff --git a/utils/plugins/DotNet/DotNetTest.psm1 b/utils/plugins/DotNet/DotNetTest.psm1 index b8bd09d..3aa8db9 100644 --- a/utils/plugins/DotNet/DotNetTest.psm1 +++ b/utils/plugins/DotNet/DotNetTest.psm1 @@ -7,12 +7,15 @@ .DESCRIPTION Resolves one or more .NET test projects (`project` or `projects`), runs tests once - via TestRunner, then publishes metrics on the shared engine context for any later + via TestRunner (Microsoft Testing Platform + coverlet.MTP only — no VSTest / + coverlet.collector), then publishes metrics on the shared engine context for any later plugin: `qualityLineCoverage`, `testResult`, `coverageLineRate` / `coverageBranchRate` / `coverageMethodRate`, method counts, `testResultsDirectory`, `coverageCoberturaPaths`. Quality gates read those keys generically (not tied to this plugin by name). When `resultsDir` (or the multi-project default TestResults folder) is used, Cobertura output is kept on disk via TestRunner `-KeepResults` so repo-root `test-results/` persists after the run. + Product solutions must place `src/global.json` with `test.runner` = + Microsoft.Testing.Platform next to the `.sln`/`.slnx`. #> if (-not (Get-Command Import-PluginDependency -ErrorAction SilentlyContinue)) {