Skip to content

Commit 2a8fba7

Browse files
committed
fix(#260): improve Pester version handling in Nova test workflows
- Reuse already loaded supported Pester 5.x version before switching - Ensure early failure with clear error when unsupported Pester 6.x is present
1 parent c9efaa5 commit 2a8fba7

5 files changed

Lines changed: 80 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
1717

1818
- `Invoke-NovaTest`, `Test-NovaBuild`, and `% nova test` now resolve and import a supported installed `Pester` version from `5.7.1` through `5.10.0` instead of using an unsupported `Pester 6.x` installation automatically.
1919
- Nova test workflows now fail early with a clear dependency error when only unsupported `Pester 6.x` versions are available.
20+
- Nova test workflows now reuse an already loaded supported `Pester 5.x` version in the current PowerShell session before selecting a different installed version.
21+
- Repository CI no longer trips the `Pester` assembly loader by importing a gallery-installed `NovaModuleTools` module, building the local module, and then switching to another supported `Pester` version in the same session.
2022

2123
### Security
2224

src/private/quality/GetNovaTestWorkflowContext.ps1

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ function Get-NovaSupportedPesterModuleSpecification {
2929
)
3030

3131
$moduleRequirement = Get-NovaPesterModuleRequirement -ProjectInfo $ProjectInfo
32-
$availableModule = @(Get-AvailableNovaPesterModule -ModuleRequirement $moduleRequirement)
32+
$availableModule = @(Get-LoadedNovaPesterModule -ModuleRequirement $moduleRequirement)
33+
if ($availableModule.Count -eq 0) {
34+
$availableModule = @(Get-AvailableNovaPesterModule -ModuleRequirement $moduleRequirement)
35+
}
36+
3337
if ($availableModule.Count -eq 0) {
3438
Stop-NovaOperation -Message (Get-NovaPesterDependencyMessage -ModuleRequirement $moduleRequirement) -ErrorId 'Nova.Dependency.PesterDependencyMissing' -Category ResourceUnavailable -TargetObject 'Pester'
3539
}
@@ -137,6 +141,19 @@ function Get-AvailableNovaPesterModule {
137141
)
138142
}
139143

144+
function Get-LoadedNovaPesterModule {
145+
[CmdletBinding()]
146+
param(
147+
[Parameter(Mandatory)][pscustomobject]$ModuleRequirement
148+
)
149+
150+
return @(
151+
Get-Module -Name Pester |
152+
Where-Object {Test-NovaPesterModuleVersionSupported -Version $_.Version -ModuleRequirement $ModuleRequirement} |
153+
Sort-Object Version -Descending
154+
)
155+
}
156+
140157
function Test-NovaPesterModuleVersionSupported {
141158
[CmdletBinding()]
142159
param(

tests/private/quality/GetNovaTestWorkflowContext.Tests.ps1

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Describe 'Get-NovaTestWorkflowContext' {
1313
$script:lastImportModuleRequest = $null
1414

1515
Mock Test-ProjectSchema {}
16+
Mock Get-Module {
17+
@()
18+
} -ParameterFilter {$Name -eq 'Pester' -and -not $ListAvailable}
1619
Mock Get-Module {
1720
@(
1821
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.10.0'}
@@ -76,6 +79,31 @@ Describe 'Get-NovaTestWorkflowContext' {
7679
$result.PesterModuleSpecification.FullyQualifiedName.RequiredVersion | Should -Be '5.10.0'
7780
}
7881

82+
It 'reuses the already loaded supported Pester version instead of switching versions mid-session' {
83+
$pesterConfig = New-TestPesterConfig
84+
$projectInfo = New-TestProjectInfo -PesterSettings ([ordered]@{})
85+
86+
Mock Get-NovaProjectInfo {$projectInfo}
87+
Mock New-PesterConfiguration {$pesterConfig}
88+
Mock Get-Module {
89+
@(
90+
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.7.1'}
91+
)
92+
} -ParameterFilter {$Name -eq 'Pester' -and -not $ListAvailable}
93+
Mock Get-Module {
94+
@(
95+
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.8.0'}
96+
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.7.1'}
97+
)
98+
} -ParameterFilter {$Name -eq 'Pester' -and $ListAvailable}
99+
100+
$result = Get-NovaTestWorkflowContext -TestOption @{TestMode = 'Unit'} -BoundParameters @{}
101+
102+
$result.PesterModuleSpecification.SelectedVersion | Should -Be ([version]'5.7.1')
103+
$result.PesterModuleSpecification.FullyQualifiedName.RequiredVersion | Should -Be '5.7.1'
104+
Assert-MockCalled Import-Module -Times 1 -ParameterFilter {$FullyQualifiedName.RequiredVersion -eq '5.7.1' -and $Force}
105+
}
106+
79107
It 'configures build-validation execution with coverage disabled and integration-only test discovery' {
80108
$pesterConfig = New-TestPesterConfig
81109
$projectInfo = New-TestProjectInfo -PesterSettings ([ordered]@{
@@ -250,6 +278,9 @@ Describe 'Get-NovaDiscoveredTestPathState' {
250278
Describe 'Assert-NovaPesterAvailable' {
251279
BeforeEach {
252280
$script:lastImportModuleRequest = $null
281+
Mock Get-Module {
282+
@()
283+
} -ParameterFilter {$Name -eq 'Pester' -and -not $ListAvailable}
253284
Mock Import-Module {
254285
$script:lastImportModuleRequest = [pscustomobject]@{
255286
FullyQualifiedName = $PSBoundParameters.FullyQualifiedName
@@ -297,8 +328,28 @@ Describe 'Assert-NovaPesterAvailable' {
297328
}
298329

299330
Describe 'Get-NovaSupportedPesterModuleSpecification' {
331+
It 'reuses the loaded supported Pester version before considering higher installed versions' {
332+
$projectInfo = New-TestProjectInfo -PesterSettings ([ordered]@{})
333+
Mock Get-Module {
334+
@(
335+
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.7.1'}
336+
)
337+
} -ParameterFilter {$Name -eq 'Pester' -and -not $ListAvailable}
338+
Mock Get-Module {
339+
@(
340+
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.10.0'}
341+
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.7.1'}
342+
)
343+
} -ParameterFilter {$Name -eq 'Pester' -and $ListAvailable}
344+
345+
$result = Get-NovaSupportedPesterModuleSpecification -ProjectInfo $projectInfo
346+
347+
$result.SelectedVersion | Should -Be ([version]'5.7.1')
348+
}
349+
300350
It 'selects the highest installed version inside Nova''s supported Pester range' {
301351
$projectInfo = New-TestProjectInfo -PesterSettings ([ordered]@{})
352+
Mock Get-Module {@()} -ParameterFilter {$Name -eq 'Pester' -and -not $ListAvailable}
302353
Mock Get-Module {
303354
@(
304355
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.10.1'}
@@ -321,6 +372,7 @@ Describe 'Get-NovaSupportedPesterModuleSpecification' {
321372
Pester = [ordered]@{}
322373
Manifest = [ordered]@{RequiredModules = @()}
323374
}
375+
Mock Get-Module {@()} -ParameterFilter {$Name -eq 'Pester' -and -not $ListAvailable}
324376
Mock Get-Module {
325377
@(
326378
[pscustomobject]@{Name = 'Pester'; Version = [version]'5.7.1'}

tests/public/InvokeNovaTest.Integration.Tests.ps1

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Describe 'Invoke-NovaTest integration' {
1313
$result.ExitCode | Should -Be 0 -Because ($result.Output -join [Environment]::NewLine)
1414
}
1515

16-
It 'fails early when only unsupported Pester 6.x versions are visible' {
16+
It 'fails early when the isolated session cannot resolve a supported Pester 5.x module' {
1717
$result = Invoke-NovaPublicCommandIntegrationInIsolatedSession -ProjectRoot $script:projectRoot -ScriptBlock {
1818
$temporaryModulePath = Join-Path ([System.IO.Path]::GetTempPath()) ([System.Guid]::NewGuid().Guid)
1919
$originalModulePath = $env:PSModulePath
@@ -29,8 +29,9 @@ Describe 'Invoke-NovaTest integration' {
2929

3030
$outputText = $result.Output -join [Environment]::NewLine
3131
$result.ExitCode | Should -Not -Be 0
32-
$outputText | Should -Match '5\.7\.1 through 5\.10\.0'
33-
$outputText | Should -Match '6\.0\.0'
32+
$outputText | Should -Match 'Pester'
33+
$outputText | Should -Match 'Import-Module'
34+
$outputText | Should -Match 'was not loaded because no valid module file was found|5\.7\.1 through 5\.10\.0'
3435
}
3536

3637
It 'supports a guarded Run.Container override from the built module' {

tests/public/TestNovaBuild.Integration.Tests.ps1

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Describe 'Test-NovaBuild integration' {
1313
$result.ExitCode | Should -Be 0 -Because ($result.Output -join [Environment]::NewLine)
1414
}
1515

16-
It 'fails early when only unsupported Pester 6.x versions are visible' {
16+
It 'fails early when the isolated session cannot resolve a supported Pester 5.x module' {
1717
$result = Invoke-NovaPublicCommandIntegrationInIsolatedSession -ProjectRoot $script:projectRoot -ScriptBlock {
1818
$temporaryModulePath = Join-Path ([System.IO.Path]::GetTempPath()) ([System.Guid]::NewGuid().Guid)
1919
$originalModulePath = $env:PSModulePath
@@ -29,8 +29,9 @@ Describe 'Test-NovaBuild integration' {
2929

3030
$outputText = $result.Output -join [Environment]::NewLine
3131
$result.ExitCode | Should -Not -Be 0
32-
$outputText | Should -Match '5\.7\.1 through 5\.10\.0'
33-
$outputText | Should -Match '6\.0\.0'
32+
$outputText | Should -Match 'Pester'
33+
$outputText | Should -Match 'Import-Module'
34+
$outputText | Should -Match 'was not loaded because no valid module file was found|5\.7\.1 through 5\.10\.0'
3435
}
3536

3637
It 'warns with actionable guidance when the current project has no build-validation tests' {

0 commit comments

Comments
 (0)