11<#
22. SYNOPSIS
3- Run VSTest for FieldWorks test assemblies with proper result parsing.
3+ Run VSTest for FieldWorks test assemblies with proper result parsing.
44
55. DESCRIPTION
6- This script runs vstest.console.exe on specified test DLLs and parses the results
7- to provide clear pass/fail/skip counts. It handles the InIsolation mode configured
8- in Test.runsettings and properly interprets exit codes.
6+ This script runs vstest.console.exe on specified test DLLs and parses the results
7+ to provide clear pass/fail/skip counts. It handles the InIsolation mode configured
8+ in Test.runsettings and properly interprets exit codes.
99
1010. PARAMETER TestDlls
11- Array of test DLL names (e.g., "FwUtilsTests.dll") or paths.
12- If just names are provided, looks in Output\Debug by default.
11+ Array of test DLL names (e.g., "FwUtilsTests.dll") or paths.
12+ If just names are provided, looks in Output\Debug by default.
1313
1414. PARAMETER OutputDir
15- Directory containing test DLLs. Defaults to Output\Debug.
15+ Directory containing test DLLs. Defaults to Output\Debug.
1616
1717. PARAMETER Filter
18- Optional VSTest filter expression (e.g., "TestCategory!=Slow").
18+ Optional VSTest filter expression (e.g., "TestCategory!=Slow").
1919
2020. PARAMETER Rebuild
21- If specified, rebuilds the test projects before running tests.
21+ If specified, rebuilds the test projects before running tests.
2222
2323. PARAMETER All
24- If specified, runs all *Tests.dll files found in OutputDir.
24+ If specified, runs all *Tests.dll files found in OutputDir.
2525
2626. EXAMPLE
27- .\Run-VsTests.ps1 -TestDlls FwUtilsTests.dll
28- Runs FwUtilsTests.dll and shows results.
27+ .\Run-VsTests.ps1 -TestDlls FwUtilsTests.dll
28+ Runs FwUtilsTests.dll and shows results.
2929
3030. EXAMPLE
31- .\Run-VsTests.ps1 -TestDlls FwUtilsTests.dll,xCoreTests.dll
32- Runs multiple test DLLs and shows aggregate results.
31+ .\Run-VsTests.ps1 -TestDlls FwUtilsTests.dll,xCoreTests.dll
32+ Runs multiple test DLLs and shows aggregate results.
3333
3434. EXAMPLE
35- .\Run-VsTests.ps1 -All
36- Runs all test DLLs in Output\Debug.
35+ .\Run-VsTests.ps1 -All
36+ Runs all test DLLs in Output\Debug.
3737
3838. EXAMPLE
39- .\Run-VsTests.ps1 -TestDlls FwUtilsTests.dll -Rebuild
40- Rebuilds the test project first, then runs tests.
39+ .\Run-VsTests.ps1 -TestDlls FwUtilsTests.dll -Rebuild
40+ Rebuilds the test project first, then runs tests.
4141#>
4242[CmdletBinding ()]
4343param (
44- [Parameter (Position = 0 )]
45- [string []]$TestDlls ,
44+ [Parameter (Position = 0 )]
45+ [string []]$TestDlls ,
4646
47- [string ]$OutputDir ,
47+ [string ]$OutputDir ,
4848
49- [string ]$Filter ,
49+ [string ]$Filter ,
5050
51- [switch ]$Rebuild ,
51+ [switch ]$Rebuild ,
5252
53- [switch ]$All
53+ [switch ]$All
5454)
5555
5656$ErrorActionPreference = ' Continue' # Don't stop on stderr output from vstest
@@ -59,63 +59,63 @@ Import-Module (Join-Path $PSScriptRoot 'FwBuildEnvironment.psm1') -Force
5959# Find repo root (where FieldWorks.sln is)
6060$repoRoot = $PSScriptRoot
6161while ($repoRoot -and -not (Test-Path (Join-Path $repoRoot " FieldWorks.sln" ))) {
62- $repoRoot = Split-Path $repoRoot - Parent
62+ $repoRoot = Split-Path $repoRoot - Parent
6363}
6464if (-not $repoRoot ) {
65- Write-Error " Could not find repository root (FieldWorks.sln)"
66- exit 1
65+ Write-Error " Could not find repository root (FieldWorks.sln)"
66+ exit 1
6767}
6868
6969# Set defaults
7070if (-not $OutputDir ) {
71- $OutputDir = Join-Path $repoRoot " Output\Debug"
71+ $OutputDir = Join-Path $repoRoot " Output\Debug"
7272}
7373
7474$runSettings = Join-Path $repoRoot " Test.runsettings"
7575$vsTestPath = Get-VSTestPath
7676
7777if (-not (Test-Path $vsTestPath )) {
78- Write-Error " vstest.console.exe not found. Install Visual Studio 2022 or Build Tools."
79- exit 1
78+ Write-Error " vstest.console.exe not found. Install Visual Studio 2022 or Build Tools."
79+ exit 1
8080}
8181
8282# Collect test DLLs
8383if ($All ) {
84- $TestDlls = Get-ChildItem $OutputDir - Filter " *Tests.dll" |
85- Where-Object { $_.Name -notmatch " \.resources\." } |
86- Select-Object - ExpandProperty Name
87- Write-Host " Found $ ( $TestDlls.Count ) test assemblies" - ForegroundColor Cyan
84+ $TestDlls = Get-ChildItem $OutputDir - Filter " *Tests.dll" |
85+ Where-Object { $_.Name -notmatch " \.resources\." } |
86+ Select-Object - ExpandProperty Name
87+ Write-Host " Found $ ( $TestDlls.Count ) test assemblies" - ForegroundColor Cyan
8888}
8989
9090if (-not $TestDlls -or $TestDlls.Count -eq 0 ) {
91- Write-Host " Usage: Run-VsTests.ps1 [-TestDlls] <dll1,dll2,...> [-All] [-Rebuild] [-Filter <expr>]" - ForegroundColor Yellow
92- Write-Host " "
93- Write-Host " Examples:"
94- Write-Host " Run-VsTests.ps1 FwUtilsTests.dll"
95- Write-Host " Run-VsTests.ps1 FwUtilsTests.dll,xCoreTests.dll"
96- Write-Host " Run-VsTests.ps1 -All"
97- Write-Host " Run-VsTests.ps1 FwUtilsTests.dll -Rebuild"
98- exit 0
91+ Write-Host " Usage: Run-VsTests.ps1 [-TestDlls] <dll1,dll2,...> [-All] [-Rebuild] [-Filter <expr>]" - ForegroundColor Yellow
92+ Write-Host " "
93+ Write-Host " Examples:"
94+ Write-Host " Run-VsTests.ps1 FwUtilsTests.dll"
95+ Write-Host " Run-VsTests.ps1 FwUtilsTests.dll,xCoreTests.dll"
96+ Write-Host " Run-VsTests.ps1 -All"
97+ Write-Host " Run-VsTests.ps1 FwUtilsTests.dll -Rebuild"
98+ exit 0
9999}
100100
101101# Rebuild if requested
102102if ($Rebuild ) {
103- Write-Host " Rebuilding test projects..." - ForegroundColor Cyan
104- foreach ($dll in $TestDlls ) {
105- $dllName = [System.IO.Path ]::GetFileNameWithoutExtension($dll )
106- $csprojPattern = Join-Path $repoRoot " Src\**\$dllName .csproj"
107- $csproj = Get-ChildItem - Path (Join-Path $repoRoot " Src" ) - Recurse - Filter " $dllName .csproj" | Select-Object - First 1
108-
109- if ($csproj ) {
110- Write-Host " Building $ ( $csproj.Name ) ..." - ForegroundColor Gray
111- $buildOutput = dotnet build $csproj.FullName - c Debug -- no- incremental - v q 2>&1
112- if ($LASTEXITCODE -ne 0 ) {
113- Write-Warning " Build failed for $ ( $csproj.Name ) "
114- $buildOutput | Write-Host
115- }
116- }
117- }
118- Write-Host " "
103+ Write-Host " Rebuilding test projects..." - ForegroundColor Cyan
104+ foreach ($dll in $TestDlls ) {
105+ $dllName = [System.IO.Path ]::GetFileNameWithoutExtension($dll )
106+ $csprojPattern = Join-Path $repoRoot " Src\**\$dllName .csproj"
107+ $csproj = Get-ChildItem - Path (Join-Path $repoRoot " Src" ) - Recurse - Filter " $dllName .csproj" | Select-Object - First 1
108+
109+ if ($csproj ) {
110+ Write-Host " Building $ ( $csproj.Name ) ..." - ForegroundColor Gray
111+ $buildOutput = dotnet build $csproj.FullName - c Debug -- no- incremental - v q 2>&1
112+ if ($LASTEXITCODE -ne 0 ) {
113+ Write-Warning " Build failed for $ ( $csproj.Name ) "
114+ $buildOutput | Write-Host
115+ }
116+ }
117+ }
118+ Write-Host " "
119119}
120120
121121# Run tests
@@ -128,86 +128,86 @@ Write-Host "Running tests..." -ForegroundColor Cyan
128128Write-Host " "
129129
130130foreach ($dll in $TestDlls ) {
131- # Resolve full path
132- if (-not [System.IO.Path ]::IsPathRooted($dll )) {
133- $dllPath = Join-Path $OutputDir $dll
134- } else {
135- $dllPath = $dll
136- }
137-
138- if (-not (Test-Path $dllPath )) {
139- Write-Warning " Not found: $dll "
140- continue
141- }
142-
143- $dllName = [System.IO.Path ]::GetFileName($dllPath )
144-
145- # Build arguments
146- $args = @ ($dllPath , " /Settings:$runSettings " )
147- if ($Filter ) {
148- $args += " /TestCaseFilter:$Filter "
149- }
150-
151- # Run vstest
152- $output = & $vsTestPath @args 2>&1
153-
154- # Parse results
155- $passed = ($output | Select-String " ^\s+Passed" ).Count
156- $failed = ($output | Select-String " ^\s+Failed" ).Count
157- $skipped = ($output | Select-String " ^\s+Skipped" ).Count
158- $exitCode = $LASTEXITCODE
159-
160- $totalPassed += $passed
161- $totalFailed += $failed
162- $totalSkipped += $skipped
163-
164- # Determine status
165- if ($failed -gt 0 ) {
166- $status = " FAIL"
167- $color = " Red"
168- } elseif ($passed -eq 0 -and $skipped -eq 0 ) {
169- $status = " NONE"
170- $color = " Yellow"
171- } else {
172- $status = " PASS"
173- $color = " Green"
174- }
175-
176- # Output result
177- $resultLine = " {0,-40} {1,6} passed, {2,4} failed, {3,4} skipped [{4}]" -f $dllName , $passed , $failed , $skipped , $status
178- Write-Host $resultLine - ForegroundColor $color
179-
180- $results += [PSCustomObject ]@ {
181- DLL = $dllName
182- Passed = $passed
183- Failed = $failed
184- Skipped = $skipped
185- Status = $status
186- Output = $output
187- }
131+ # Resolve full path
132+ if (-not [System.IO.Path ]::IsPathRooted($dll )) {
133+ $dllPath = Join-Path $OutputDir $dll
134+ } else {
135+ $dllPath = $dll
136+ }
137+
138+ if (-not (Test-Path $dllPath )) {
139+ Write-Warning " Not found: $dll "
140+ continue
141+ }
142+
143+ $dllName = [System.IO.Path ]::GetFileName($dllPath )
144+
145+ # Build arguments
146+ $args = @ ($dllPath , " /Settings:$runSettings " )
147+ if ($Filter ) {
148+ $args += " /TestCaseFilter:$Filter "
149+ }
150+
151+ # Run vstest
152+ $output = & $vsTestPath @args 2>&1
153+
154+ # Parse results
155+ $passed = ($output | Select-String " ^\s+Passed" ).Count
156+ $failed = ($output | Select-String " ^\s+Failed" ).Count
157+ $skipped = ($output | Select-String " ^\s+Skipped" ).Count
158+ $exitCode = $LASTEXITCODE
159+
160+ $totalPassed += $passed
161+ $totalFailed += $failed
162+ $totalSkipped += $skipped
163+
164+ # Determine status
165+ if ($failed -gt 0 ) {
166+ $status = " FAIL"
167+ $color = " Red"
168+ } elseif ($passed -eq 0 -and $skipped -eq 0 ) {
169+ $status = " NONE"
170+ $color = " Yellow"
171+ } else {
172+ $status = " PASS"
173+ $color = " Green"
174+ }
175+
176+ # Output result
177+ $resultLine = " {0,-40} {1,6} passed, {2,4} failed, {3,4} skipped [{4}]" -f $dllName , $passed , $failed , $skipped , $status
178+ Write-Host $resultLine - ForegroundColor $color
179+
180+ $results += [PSCustomObject ]@ {
181+ DLL = $dllName
182+ Passed = $passed
183+ Failed = $failed
184+ Skipped = $skipped
185+ Status = $status
186+ Output = $output
187+ }
188188}
189189
190190# Summary
191191Write-Host " "
192192Write-Host (" =" * 70 ) - ForegroundColor Cyan
193193$summaryLine = " TOTAL: {0} passed, {1} failed, {2} skipped" -f $totalPassed , $totalFailed , $totalSkipped
194194if ($totalFailed -gt 0 ) {
195- Write-Host $summaryLine - ForegroundColor Red
196- $exitCode = 1
195+ Write-Host $summaryLine - ForegroundColor Red
196+ $exitCode = 1
197197} else {
198- Write-Host $summaryLine - ForegroundColor Green
199- $exitCode = 0
198+ Write-Host $summaryLine - ForegroundColor Green
199+ $exitCode = 0
200200}
201201
202202# Show failures if any
203203if ($totalFailed -gt 0 ) {
204- Write-Host " "
205- Write-Host " Failed tests:" - ForegroundColor Red
206- foreach ($r in $results | Where-Object { $_.Failed -gt 0 }) {
207- Write-Host " "
208- Write-Host " === $ ( $r.DLL ) ===" - ForegroundColor Yellow
209- $r.Output | Select-String " ^\s+Failed" - Context 0 , 5 | ForEach-Object { Write-Host $_ }
210- }
204+ Write-Host " "
205+ Write-Host " Failed tests:" - ForegroundColor Red
206+ foreach ($r in $results | Where-Object { $_.Failed -gt 0 }) {
207+ Write-Host " "
208+ Write-Host " === $ ( $r.DLL ) ===" - ForegroundColor Yellow
209+ $r.Output | Select-String " ^\s+Failed" - Context 0 , 5 | ForEach-Object { Write-Host $_ }
210+ }
211211}
212212
213213exit $exitCode
0 commit comments