Skip to content

Commit 3db1351

Browse files
gavinbarronCopilot
andcommitted
test: migrate solution tests to xUnit v3 and MTP
Align Reader with Hidi's support/v2 test dependencies and use native solution-wide MTP execution in CI, releases, local scripts and editor tasks. Preserve signed framework targets, test classification, TRX publication and scoped OpenCover/Cobertura coverage. Refs #885 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d5321d35-1d8c-469c-86bf-08e0856ceeee
1 parent 11337bf commit 3db1351

16 files changed

Lines changed: 119 additions & 78 deletions

‎.azure-pipelines/ci-build.yml‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ extends:
4040
os: windows
4141
demands:
4242
- msbuild
43-
- vstest
4443
customBuildTags:
4544
- ES365AIMigrationTooling
4645
stages:
@@ -81,7 +80,7 @@ extends:
8180
version: 8.x
8281

8382
- task: UseDotNet@2
84-
displayName: 'Use .NET 10 for hidi tests'
83+
displayName: 'Use .NET 10 for Microsoft.Testing.Platform'
8584
inputs:
8685
version: 10.x
8786

@@ -114,19 +113,20 @@ extends:
114113
projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.OData.sln'
115114
arguments: '--configuration $(BuildConfiguration) --no-incremental'
116115

117-
# Both test projects are in the solution, but SDK10 cannot run MTP via VSTest.
118-
# Keep OData on VSTest and invoke the hidi MTP executable separately.
119-
- task: DotNetCoreCLI@2
120-
displayName: 'test'
121-
inputs:
122-
command: test
123-
projects: '$(Build.SourcesDirectory)\test\Microsoft.OpenAPI.OData.Reader.Tests\Microsoft.OpenAPI.OData.Reader.Tests.csproj'
124-
arguments: '--configuration $(BuildConfiguration) --no-build'
125-
126116
- pwsh: |
127-
dotnet run --project test\Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj -c $(buildConfiguration) --no-build -- --minimum-expected-tests 1
117+
dotnet test --solution Microsoft.OpenApi.OData.sln -c $(buildConfiguration) --no-build --results-directory '$(Agent.TempDirectory)\TestResults' -- --minimum-expected-tests 1 --report-trx --report-azdo
128118
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
129-
displayName: 'Test hidi (Microsoft.Testing.Platform)'
119+
displayName: 'Test solution (Microsoft.Testing.Platform)'
120+
121+
- task: PublishTestResults@2
122+
displayName: 'Publish solution test results'
123+
condition: succeededOrFailed()
124+
inputs:
125+
testResultsFormat: VSTest
126+
testResultsFiles: '$(Agent.TempDirectory)\TestResults\*.trx'
127+
mergeTestResults: true
128+
failTaskOnFailedTests: true
129+
failTaskOnMissingResultsFile: true
130130

131131
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5
132132
displayName: 'ESRP CodeSigning'

‎.azure-pipelines/hidi-release.yml‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,29 @@ extends:
115115
- pwsh: |
116116
dotnet build src\Microsoft.OpenApi.Hidi\Microsoft.OpenApi.Hidi.csproj -c $(buildConfiguration) -p:GeneratePackageOnBuild=false
117117
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
118-
dotnet run --project test\Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj -c $(buildConfiguration) -- --minimum-expected-tests 1
118+
displayName: Build hidi
119+
- pwsh: |
120+
dotnet test --solution Microsoft.OpenApi.OData.sln -c $(buildConfiguration) --results-directory '$(Agent.TempDirectory)\TestResults' -- --minimum-expected-tests 1 --report-trx --report-azdo
119121
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
122+
displayName: Test solution (Microsoft.Testing.Platform)
123+
- task: PublishTestResults@2
124+
displayName: Publish solution test results
125+
condition: succeededOrFailed()
126+
inputs:
127+
testResultsFormat: VSTest
128+
testResultsFiles: '$(Agent.TempDirectory)\TestResults\*.trx'
129+
mergeTestResults: true
130+
failTaskOnFailedTests: true
131+
failTaskOnMissingResultsFile: true
132+
- pwsh: |
120133
dotnet publish src\Microsoft.OpenApi.Hidi\Microsoft.OpenApi.Hidi.csproj -c $(buildConfiguration) -r win-x64 --self-contained true -p:PublishSingleFile=true -p:PackAsTool=false -p:GeneratePackageOnBuild=false -o artifacts\hidi\win-x64
121134
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
122135
& .\artifacts\hidi\win-x64\Microsoft.OpenApi.Hidi.exe --help
123136
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
124137
New-Item -ItemType Directory -Force artifacts\hidi\signing | Out-Null
125138
Copy-Item src\Microsoft.OpenApi.Hidi\bin\$(buildConfiguration)\net8.0\Microsoft.OpenApi.Hidi.dll artifacts\hidi\signing
126139
Copy-Item artifacts\hidi\win-x64\Microsoft.OpenApi.Hidi.exe artifacts\hidi\signing
127-
displayName: Build, test and stage hidi binaries
140+
displayName: Stage hidi binaries
128141
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5
129142
displayName: Sign hidi DLL and Windows executable
130143
inputs:

‎.github/workflows/ci-cd.yml‎

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,21 +88,18 @@ jobs:
8888
id: run_unit_tests
8989
shell: pwsh
9090
run: |
91-
$testProjectsArray = @(
92-
'.\test\Microsoft.OpenAPI.OData.Reader.Tests\Microsoft.OpenAPI.OData.Reader.Tests.csproj'
93-
)
94-
95-
$testProjectsArray | ForEach-Object {
96-
dotnet test $PSItem `
97-
-c Release
98-
}
99-
100-
- name: Run hidi tests (Microsoft.Testing.Platform)
101-
shell: pwsh
102-
run: |
103-
dotnet run --project .\test\Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj -c Release -- --minimum-expected-tests 1
91+
$resultsDirectory = Join-Path $PWD 'artifacts' 'test-results'
92+
dotnet test --solution Microsoft.OpenApi.OData.sln -c Release -p:EnableWindowsTargeting=true --results-directory $resultsDirectory -- --minimum-expected-tests 1 --report-trx --report-gh
10493
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
10594
95+
- name: Upload test results
96+
if: always()
97+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
98+
with:
99+
name: test-results
100+
path: artifacts/test-results
101+
if-no-files-found: error
102+
106103
- name: Pack and install hidi locally
107104
shell: pwsh
108105
run: |

‎.github/workflows/sonarcloud.yml‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,25 @@ jobs:
122122
- name: Build and analyze
123123
env:
124124
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
125-
CollectCoverage: true
126-
CoverletOutputFormat: 'opencover' # https://github.com/microsoft/vstest/issues/4014#issuecomment-1307913682
127125
shell: pwsh
128126
run: |
129-
dotnet tool run dotnet-sonarscanner begin /k:"microsoft_OpenAPI.NET.OData" /o:"microsoft" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="test/**/coverage.net8.0.opencover.xml,artifacts/hidi/coverage/*opencover*.xml" /d:sonar.coverageReportPaths="artifacts/hidi/powershell-coverage/sonar-coverage.xml"
127+
dotnet tool run dotnet-sonarscanner begin /k:"microsoft_OpenAPI.NET.OData" /o:"microsoft" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="artifacts/test-results/*opencover*.xml" /d:sonar.coverageReportPaths="artifacts/hidi/powershell-coverage/sonar-coverage.xml"
128+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
130129
dotnet workload restore
130+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
131131
dotnet build
132-
dotnet test test\Microsoft.OpenAPI.OData.Reader.Tests\Microsoft.OpenAPI.OData.Reader.Tests.csproj --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
133132
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
134-
dotnet run --project test\Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj --no-build -- --minimum-expected-tests 1 --coverlet --coverlet-output-format opencover --coverlet-include "[Microsoft.OpenApi.Hidi]*" --results-directory artifacts\hidi\coverage
133+
dotnet test --solution Microsoft.OpenApi.OData.sln --no-build --results-directory artifacts\test-results -- --minimum-expected-tests 1 --report-trx --report-gh --coverlet --coverlet-output-format opencover --coverlet-include "[Microsoft.OpenApi.OData.Reader]*" --coverlet-include "[Microsoft.OpenApi.Hidi]*"
135134
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
136-
if (-not (Get-ChildItem artifacts\hidi\coverage -Filter '*opencover*.xml')) { throw "Hidi OpenCover report was not generated." }
135+
$reports = @(Get-ChildItem artifacts\test-results -Filter '*opencover*.xml')
136+
if ($reports.Count -ne 2) { throw "Expected an OpenCover report from each test project." }
137137
dotnet tool run dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
138+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
139+
140+
- name: Upload test and coverage results
141+
if: always()
142+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
143+
with:
144+
name: sonar-test-results
145+
path: artifacts/test-results
146+
if-no-files-found: error

‎.vscode/tasks.json‎

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,21 @@
2121
"group": "test",
2222
"args": [
2323
"test",
24+
"--solution",
2425
"${workspaceFolder}/Microsoft.OpenApi.OData.sln",
25-
"/property:GenerateFullPaths=true",
26-
"/consoleloggerparameters:NoSummary",
27-
"--collect:\"XPlat Code Coverage\""
26+
"-p:EnableWindowsTargeting=true",
27+
"--results-directory",
28+
"${workspaceFolder}/artifacts/test-results",
29+
"--",
30+
"--minimum-expected-tests",
31+
"1",
32+
"--coverlet",
33+
"--coverlet-output-format",
34+
"cobertura",
35+
"--coverlet-include",
36+
"[Microsoft.OpenApi.OData.Reader]*",
37+
"--coverlet-include",
38+
"[Microsoft.OpenApi.Hidi]*"
2839
],
2940
"problemMatcher": "$msCompile"
3041
},
@@ -35,15 +46,15 @@
3546
"linux": {
3647
"command": "rm",
3748
"args": [
38-
"-r",
39-
"${workspaceFolder}/test/Microsoft.OpenAPI.OData.Reader.Tests/TestResults"
49+
"-rf",
50+
"${workspaceFolder}/artifacts/test-results"
4051
]
4152
},
4253
"windows": {
4354
"command": "powershell",
4455
"args": [
4556
"-command",
46-
"Remove-Item -Recurse -Include TestResults -Path ${workspaceFolder}/tests"
57+
"if (Test-Path -LiteralPath '${workspaceFolder}/artifacts/test-results') { Remove-Item -Recurse -LiteralPath '${workspaceFolder}/artifacts/test-results' }"
4758
]
4859
}
4960
},
@@ -54,14 +65,14 @@
5465
"linux":{
5566
"command": "reportgenerator",
5667
"args": [
57-
"-reports:${workspaceFolder}/tests/**/coverage.cobertura.xml",
68+
"-reports:${workspaceFolder}/artifacts/test-results/*cobertura*.xml",
5869
"-targetdir:${workspaceFolder}/reports/coverage"
5970
],
6071
},
6172
"windows": {
6273
"command": "reportgenerator",
6374
"args": [
64-
"-reports:${workspaceFolder}\\test\\**\\coverage.cobertura.xml",
75+
"-reports:${workspaceFolder}\\artifacts\\test-results\\*cobertura*.xml",
6576
"-targetdir:${workspaceFolder}\\reports\\coverage"
6677
]
6778
},
@@ -72,7 +83,7 @@
7283
"dependsOrder": "sequence"
7384
},
7485
{
75-
"label": "coverage:launch",
86+
"label": "coverage:open",
7687
"type": "shell",
7788
"linux": {
7889
"command": "xdg-open",
@@ -100,7 +111,7 @@
100111
"dependsOrder": "sequence",
101112
"dependsOn": [
102113
"coverage:unit",
103-
"coverage:launch"
114+
"coverage:open"
104115
]
105116
},
106117
{

‎CONTRIBUTING.md‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,29 @@ OpenAPI.net.OData is a mono-repo containing source code for the following packag
1212

1313
[Microsoft.OpenApi.Hidi](src/Microsoft.OpenApi.Hidi/readme.md) is a .NET tool,
1414
not an OData library package. Install the .NET 10 SDK and .NET 8 runtime to build
15-
and test both projects. Do not change the solution-wide test runner: OData uses
16-
VSTest and hidi uses Microsoft.Testing.Platform.
15+
and test both projects. Both test projects use xUnit v3 and
16+
Microsoft.Testing.Platform, selected by `global.json`. Reader tests still target
17+
.NET 8; Hidi tests target .NET 10.
1718

1819
```powershell
1920
dotnet build Microsoft.OpenApi.OData.sln -c Release
20-
dotnet test test\Microsoft.OpenAPI.OData.Reader.Tests\Microsoft.OpenAPI.OData.Reader.Tests.csproj -c Release
21-
dotnet run --project test\Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj -c Release -- --minimum-expected-tests 1
21+
dotnet test --solution Microsoft.OpenApi.OData.sln -c Release --no-build -- --minimum-expected-tests 1
2222
```
2323

24+
On non-Windows hosts, pass `-p:EnableWindowsTargeting=true` to both commands
25+
because the solution also contains the Windows-only GUI project.
26+
Use `--project <path>` instead of `--solution <path>` for a single test project.
27+
MTP options replace VSTest's `--logger`, `--collect`, and MSBuild coverage options:
28+
29+
```powershell
30+
dotnet test --solution Microsoft.OpenApi.OData.sln -c Release --no-build --results-directory artifacts\test-results -- --minimum-expected-tests 1 --report-trx --coverlet --coverlet-output-format cobertura --coverlet-include "[Microsoft.OpenApi.OData.Reader]*" --coverlet-include "[Microsoft.OpenApi.Hidi]*"
31+
```
32+
33+
This produces separate TRX and coverage reports for each test assembly.
34+
CI uses `--report-gh` for GitHub Actions and `--report-azdo` with TRX publication
35+
for Azure DevOps. SonarCloud collects OpenCover reports for both projects in
36+
`artifacts/test-results`, alongside the separately measured Pester helper coverage.
37+
2438
Hidi uses published OpenAPI core/YAML packages and the local OData project. Its
2539
public-only signing key preserves assembly identity and friend-assembly access;
2640
never add the source repository's private strong-name key. Production signing

‎README.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ The command remains `hidi`.
9595

9696
The `support/v2` branch maintains hidi 2.x separately from the OData library
9797
version. Hidi requires .NET 8 to run; building the repository and running hidi
98-
tests requires the .NET 10 SDK. Existing OData tests still use .NET 8 and VSTest.
98+
tests requires the .NET 10 SDK. Both test projects use xUnit v3 and
99+
Microsoft.Testing.Platform; OData tests still target .NET 8. Run them together
100+
with `dotnet test --solution Microsoft.OpenApi.OData.sln -c Release -- --minimum-expected-tests 1`
101+
(add `-p:EnableWindowsTargeting=true` on non-Windows hosts). See
102+
[contributing](CONTRIBUTING.md#hidi) for coverage and reporting commands.
99103

100104
Hidi's filtered history was imported with a merge, not squashed. **Merge this
101105
migration PR using a merge commit, not squash or rebase**, so the canonical

‎build.ps1‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ ForEach ($ver in $SNVersions)
103103
}
104104

105105
# Other variables
106-
$ProductProj = $ENLISTMENT_ROOT + "\src\Microsoft.OpenAPI.OData.Reader\Microsoft.OpenApi.OData.Reader.csproj"
107-
$TESTProj = $ENLISTMENT_ROOT + "\test\Microsoft.OpenAPI.OData.Reader.Tests\Microsoft.OpenApi.OData.Reader.Tests.csproj"
106+
$Solution = $ENLISTMENT_ROOT + "\Microsoft.OpenApi.OData.sln"
108107

109108
$TESTDIR = $ENLISTMENT_ROOT + "\bin\$Configuration\Test\net472"
110109
$PRODUCTDIR = $ENLISTMENT_ROOT + "\bin\$Configuration\net472"
@@ -186,13 +185,10 @@ Function BuildProcess
186185

187186
$script:BUILD_START_TIME = Get-Date
188187

189-
Write-Host "Build Product ..."
188+
Write-Host "Build Solution ..."
190189

191-
& dotnet.exe build $ProductProj -c $Configuration
192-
193-
Write-Host "Build Test ..."
194-
195-
& dotnet.exe build $TESTProj -c $Configuration
190+
& dotnet.exe build $Solution -c $Configuration
191+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
196192

197193
Write-Host "Build Done" -ForegroundColor $Success
198194
$script:BUILD_END_TIME = Get-Date
@@ -204,7 +200,8 @@ Function TestProcess
204200

205201
$script:TEST_START_TIME = Get-Date
206202

207-
& dotnet test $TESTProj -c $Configuration
203+
& dotnet test --solution $Solution -c $Configuration --no-build -- --minimum-expected-tests 1
204+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
208205

209206
Write-Host "Test Done" -ForegroundColor $Success
210207
$script:TEST_END_TIME = Get-Date

‎global.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
"version": "10.0.100",
44
"rollForward": "latestFeature",
55
"allowPrerelease": false
6+
},
7+
"test": {
8+
"runner": "Microsoft.Testing.Platform"
69
}
710
}

‎test/Microsoft.OpenAPI.OData.Reader.Tests/Common/EdmModelHelper.cs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
using System.Collections.Generic;
1616
using System.Text;
1717
using Microsoft.OData.Edm.Validation;
18-
using Xunit.Abstractions;
1918

2019
namespace Microsoft.OpenApi.OData.Tests
2120
{

0 commit comments

Comments
 (0)