Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pester Test Execution Fails When $WhatIfPreference is Enabled #2585

Open
3 tasks done
zzt108 opened this issue Dec 12, 2024 · 5 comments
Open
3 tasks done

Pester Test Execution Fails When $WhatIfPreference is Enabled #2585

zzt108 opened this issue Dec 12, 2024 · 5 comments

Comments

@zzt108
Copy link

zzt108 commented Dec 12, 2024

Checklist

What is the issue?

Problem Description: When $WhatIfPreference is set to $true, Pester test execution fails with multiple side effects:

  1. Generates excessive "What if" messages during test discovery and execution
  2. Prevents actual command execution
  3. Causes test framework to fail silently or with cryptic error messages

Specific Symptoms:

  • Test discovery completes
  • Test execution fails
  • Multiple "What if" messages appear in output
  • Error messages like "Cannot bind argument to parameter 'Root' because it is null"

Root Cause: The $WhatIfPreference setting affects command execution globally, interfering with Pester's internal test mechanisms. Simply setting it to $false within a function's local scope does not consistently resolve the issue.

Expected Behavior

$WhatIfPreference should not cause exception

Steps To Reproduce

I use ipynb. I put the following into a cell:

$WhatIfPreference = $true

Invoke-Pester "Firewall.Tests.ps1" 

Describe your environment

Pester version : 5.6.1 C:\Program Files\WindowsPowerShell\Modules\Pester\5.6.1\Pester.psm1
PowerShell version : 5.1.22621.4391
OS version : Microsoft Windows NT 10.0.22631.0

Possible Solution?

this approach works:

$originalGlobalWhatIf = $global:WhatIfPreference
$originalLocalWhatIf = $WhatIfPreference
$originalPSDefaultWhatIf = $PSDefaultParameterValues['*:WhatIf']

try {
    $global:WhatIfPreference = $false
    $WhatIfPreference = $false
    $PSDefaultParameterValues['*:WhatIf'] = $false
    
    # Test execution
}
finally {
    $global:WhatIfPreference = $originalGlobalWhatIf
    $WhatIfPreference = $originalLocalWhatIf
    $PSDefaultParameterValues['*:WhatIf'] = $originalPSDefaultWhatIf
}
@zzt108
Copy link
Author

zzt108 commented Dec 12, 2024

here is the content of Firewall.Tests.ps1:

param(
    [string[]]$FirewallRules = @()
)

Describe "Firewall Rule Validation" {
    BeforeAll {
        $script:rulesToTest = if ($FirewallRules.Count -gt 0) { $FirewallRules } else {
            @(
                "Rule1Name",
                "Rule2Name",
                "Rule3Name"
            )
        }            
    }
    # If no rules are passed, use default rules

    It "Should have required firewall rules" {
        foreach ($ruleName in $script:rulesToTest) {
            $firewallRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
            
            $firewallRule | Should -Not -BeNullOrEmpty -Because "Firewall rule '$ruleName' should exist"
            $firewallRule.Enabled | Should -Be $true -Because "Firewall rule '$ruleName' should be enabled"
        }
    }

    # Optional: More specific rule validation
    It "Should have correct rule configurations" {
        foreach ($ruleName in $script:rulesToTest) {
            $firewallRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
            $firewallRule | Should -Not -BeNullOrEmpty -Because "Firewall rule '$ruleName' should exist"            
            if ($firewallRule) {
                # Example additional checks
                $firewallRule.Action | Should -Be "Allow" -Because "Rule '$ruleName' should allow traffic"
                # Add more specific assertions as needed
            }
        }
    }
}

@nohwnd
Copy link
Member

nohwnd commented Dec 13, 2024

Cool that no-one saw that before. We should either detect that and throw, or pass the variable down skipping the pester stuff. Both solutions seem bad.

@zzt108
Copy link
Author

zzt108 commented Dec 17, 2024

I guess somewhere $PSCmdlet.ShouldProcess prevents execution of important initialization steps for registry mocking. If those important steps would be executed even if $WhatIfPreference is true, then the problem would be solved.

Another possibility is to save the state of $WhatIfPreference before execution, setting it to $false and finally restoring, as in the example I provided

@nohwnd
Copy link
Member

nohwnd commented Dec 17, 2024

Sorry I meant bad == hard to implement and track. And relatively expensive to restore the whatIf before every user scope executed script block.

@zzt108
Copy link
Author

zzt108 commented Dec 17, 2024

Then maybe remains throwing an exception with an explanation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants