pester / Pester

Pester is the ubiquitous test and mock framework for PowerShell.
https://pester.dev/
Other
3.08k stars 470 forks source link

Using same data with two or more containers fail #2073

Closed johlju closed 1 year ago

johlju commented 3 years ago

General summary of the issue

Using the same data hashtable for tests script files that contains parameters, and is using a parameter with [Parameter(ValueFromRemainingArguments = $true)], fails.

This might have been introduced in Pester v5.3.0 because we are seeing this in the pipeline today, and have not seen it before. I wondering if this is a bug in Pester (or can be fixed in Pester), or if this is by design, then I must use the workaround (see possible solution below) in our pipeline.

The error is thrown here:

https://github.com/pester/Pester/blob/a5bdc2f19cca5a955db2646c49953f5ce7e6c854/src/Pester.Runtime.ps1#L2479

Describe your environment

Pester version     : 5.3.0 C:\source\SqlServerDsc\output\RequiredModules\Pester\5.3.0\Pester.psm1
PowerShell version : 7.1.4
OS version         : Microsoft Windows NT 10.0.19043.0

Steps to reproduce

1. Create test script file

Save the test script file ScriptParameterIssue.Tests.ps1:

param
(
    $Param1,
    $Param2,

    [Parameter(ValueFromRemainingArguments = $true)]
    $Args
)

Describe 'Test script parameter' {
    It 'Should do something' {
        $true | Should -BeTrue
    }
}

2. Run the test script

Run the following code, it will throw an error:

$pesterData = @{
    Param1        = '1'
    Param2        = '2'
    Param3        = '3'
}

$pesterConfiguration = [PesterConfiguration]::Default
$pesterConfiguration.Run.Container = @(
    New-PesterContainer -Path ScriptParameterIssue.Tests.ps1 -Data $pesterData
    New-PesterContainer -Path ScriptParameterIssue.Tests.ps1 -Data $pesterData
)

Invoke-Pester -Configuration $pesterConfiguration

$pesterConfiguration.Run.Container.Value[0].Data

Expected Behavior

Should not throw an error.

Current Behavior

Throws an error saying:

[-] Discovery in C:\source\SqlServerDsc\ScriptParameterIssue.Tests.ps1 failed with:
System.Management.Automation.ParameterBindingException: A parameter cannot be found that matches parameter name 'Param3'

Possible Solution? (optional)

The problem seems to be that Pester is changing the content of the container data hashtable, adding a new property Args, when discovery run on the first test. Then the second script file gets the wrong data since the data property for all containers point to the same hashtable.

A workaround is to make sure to clone the hashtable containing the data when passing it to New-PesterContainer.

$pesterConfiguration.Run.Container = @(
    New-PesterContainer -Path ScriptParameterIssue.Tests.ps1 -Data $pesterData.Clone()
    New-PesterContainer -Path ScriptParameterIssue.Tests.ps1 -Data $pesterData.Clone()
)
nohwnd commented 3 years ago

Ah cool. I thought we are cloning the data on input.

fflaten commented 3 years ago

We do when processing foreach/testcases, but I probably forgot with container data in #1986.

nohwnd commented 3 years ago

I am fixing this, the same way we fixed the others. Shallow copy, to avoid the backwrites into the hashtable. But not full clone to avoid unnecessary perf hit.