简体   繁体   English

Pester 5 - 在嵌套循环中访问多个变量

[英]Pester 5 - Access Multiple Variables in Nested Loop

I am converting Pester tests from V4 to V5 and in line with the best practices, moving the loops from foreach() to Describe -ForEach{} .我正在将 Pester 测试从 V4 转换为 V5,并根据最佳实践将循环从foreach()移动到Describe -ForEach{} The tests are a standard set that checks if each function has comment based help and this requires multiple nested loops.这些测试是一个标准集,用于检查每个 function 是否具有基于评论的帮助,这需要多个嵌套循环。

This question is similar to Pester 5 variable scoping and Working with nested foreach and I have referred to Data Driven Tests , but my problem goes deeper as firstly, I need multiple levels of nested loops and secondly, I need access to multiple variables.这个问题类似于Pester 5 variable scopingWorking with nested foreach并且我已经提到了Data Driven Tests ,但我的问题更深入,因为首先,我需要多层嵌套循环,其次,我需要访问多个变量。 The first variable $helpParameterNames is used by the loop and the value of each row is checked to see if it exists in the second variable $parameterNames循环使用第一个变量$helpParameterNames并检查每一行的值以查看它是否存在于第二个变量$parameterNames

V4 In V4, the arrays are accessible throughout the whole set of Describe/Context/It blocks so when I get to the last foreach loop, both $helpParameterNames and $parameterNames are accessible. V4在 V4 中,arrays 在整组 Describe/Context/It 块中都可以访问,因此当我到达最后一个foreach循环时, $helpParameterNames$parameterNames都可以访问。

$commands = Get-Command -Module ModuleName

foreach ($command in $commands) {
    $commandName = $command.Name
    $help = Get-Help $commandName -ErrorAction SilentlyContinue
    
    Describe "Test help for $commandName" -Tag Help {
        
      <It Tests Removed>
        
        Context "Test parameter help for $commandName" {            
            $common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable'
            $parameters = $command.ParameterSets.Parameters | Sort-Object -Property Name -Unique | Where-Object Name -notin $common
            $parameterNames = $parameters.Name
            $helpParameterNames = $help.Parameters.Parameter.Name | Sort-Object -Unique
            
            foreach ($parameter in $parameters) {
                $parameterName = $parameter.Name
                $parameterHelp = $help.parameters.parameter | Where-Object Name -EQ $parameterName               
                
                <It Tests Removed>
            }
            
            foreach ($helpParm in $helpParameterNames) {
                It "Should find parameter $helpParm in the function" {
                    $helpParm -in $parameterNames | Should Be $true
                }
            }
        }
    }

V5 In V5 as the setup code has to be defined in the BeforeDiscovery block, I can't get it to be available in the sub-blocks automatically. V5在 V5 中,因为必须在BeforeDiscovery块中定义设置代码,所以我无法让它自动在子块中可用。 I can make it accessible by passing the array into the -ForEach as a HashTable, but then it will treat it as 1 object and not iterate over it, which is fine for $help , but not for $helpParameterNames我可以通过将数组作为哈希表传递给-ForEach来使其可访问,但随后它将把它视为 1 object 而不是对其进行迭代,这对$help很好,但对$helpParameterNames

BeforeDiscovery {
    $commands = Get-Command -Module ModuleName
}

Describe "Help Rules" -Tags Build, Help -ForEach $commands {
    BeforeDiscovery {
        $commandName = $_.Name

        $common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable'
        $parameters = (Get-Command $commandName).ParameterSets.Parameters | Where-Object -Property Name -NotIn $common | Sort-Object -Property Name -Unique
        $parameterNames = $parameters.Name
        $help = Get-Help $commandName -Full -ErrorAction SilentlyContinue
    }

    Context "General Rules for $commandName" -ForEach @{help = $help} {

        <It Tests Removed>

        Describe "Parameter Rules for <parameter.Name>" -Tags Help, Parameter -ForEach $parameters {
        
            BeforeAll {
                $parameter = $_.parameters
                $helpParameterNames = $help.Parameters.Parameter.Name | Sort-Object -Unique
                $parameterHelp = $help.parameters.parameter | Where-Object Name -EQ $parameter.Name
            }

            <It Tests Removed>
        }

        It "Should find parameter <helpParameter> in the function" -Tag Help, Parameter -ForEach $helpParameterNames {
            
            BeforeAll {
                $helpParameter = $_
            }

            $helpParameter -in $parameterNames | Should -BeTrue
        }
    }

How do I get the last -ForEach to have access to both $parameterNames from the BeforeDiscovery block and also $helpParameterNames from the parent loop?如何让最后一个-ForEach能够访问BeforeDiscovery块中的$parameterNames parameterNames 以及父循环中的$helpParameterNames

This is a unique situation and the solution is that some code has to be repeated both in BeforeDiscovery and BeforeAll .这是一种独特的情况,解决方案是必须在BeforeDiscoveryBeforeAll中重复一些代码。 Adding the code to BeforeDiscovery means that it can be used in the Context -ForEach and adding the code to BeforeAll means that it is accessible as a single object inside the child Describe blocks.将代码添加到BeforeDiscovery意味着它可以在Context -ForEach中使用,将代码添加到BeforeAll意味着它可以作为子Describe块中的单个 object 访问。

Describe "Help Rules" -Tags Build, Help -ForEach $commands {

    BeforeDiscovery {
        $common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable'
        $parameters = (Get-Command $_.Name).ParameterSets.Parameters | Where-Object -Property Name -NotIn $common | Sort-Object -Property Name -Unique
        $help = Get-Help $_.Name -Full -ErrorAction SilentlyContinue
        $helpParameterNames = $help.Parameters.Parameter.Name | Sort-Object -Unique
    }
    
    BeforeAll {
        $commandName = $_.Name

        $help = Get-Help $commandName -Full -ErrorAction SilentlyContinue
        $helpParameterNames = $help.Parameters.Parameter.Name | Sort-Object -Unique
        
        #Define this both in BeforeDiscovery and BeforeAll as it is needed both in the ForEach and also as an array
        $common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable'
        $parameters = (Get-Command $_.Name).ParameterSets.Parameters | Where-Object -Property Name -NotIn $common | Sort-Object -Property Name -Unique
        $parameterNames = $parameters.Name
    }

    Context "General Rules for <commandName>" -ForEach $parameters {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM