3

编辑

问题的关键是:如何访问BeforeDiscovery在我的块中的块中声明的变量,这些变量没有被构造It传递?it -foreach $var


我很难适应 Pester 5 中的发现/运行阶段和变量范围

背景

我们正在移动服务器,我要测试的是

  1. 上的每一股serverA存在于上serverB
  2. 上的每个可读共享serverA也可以在 上读取serverB

使用 Pester 5,下面的代码按预期运行,但要使其正常工作,我必须检索$toShares两次。在我的实际测试中检索共享是使用 anet view并且是一个相当长的运行操作。

  1. 我必须$toShares在发现阶段检索以构建$readableFromShares列表
  2. 我必须$toShares在 BeforeAll 块中检索相同的内容才能在should exists测试中使用它们

问题

我怎样才能最好地重组我的测试,以便我只需要检索$toShares一次?

测试代码

$PesterPreference = [PesterConfiguration]::Default
$PesterPreference.Output.Verbosity = 'Detailed'

function Test-Path {$True} # hide the real Test-Path function
Describe "Describe" -ForEach @(
    @{fromServer ='serverA'; toServer = 'serverB'}    
    @{fromServer ='serverC'; toServer = 'serverD'}    
    ){
    
    BeforeDiscovery {
        $fromShares = 'share1', 'share2', 'share3'
        # $toShares is needed here to construct the readableFromShares array
        $toShares = 'share1', 'share2'
        $readableFromShares = $fromShares | 
            Where-Object {$toShares -contains $_} | 
            Where-Object {Test-Path "\\$($fromServer)\$($_)"}
    }
     
    Context "<fromServer> samba shares should exist on <toServer>" { 
        BeforeAll {
            # the "same" $toShares is needed here to be available in the exist tests
            $toShares = 'share1', 'share2'
        }
        It "Does \\<toServer>\<_> exist" -ForEach $fromShares {
            $toShares -contains $_ | Should -Be $true
        }
    }

    Context "Readable <fromServer> samba shares should als be readable on <toServer>" {
        It "<_> is readable on <fromServer>. \\<toServer>\<_> should also be readable." -ForEach $readableFromShares {
            Test-Path "\\$($toServer)\$($_)"| Should -Be $True
        }
    }
}

输出 包括两个故意失败的测试

输出测试用例


编辑

测试用例包括

  1. 两个从/到服务器(io 一个)
  2. 每组服务器的不同共享名

测试

$PesterPreference = [PesterConfiguration]::Default
$PesterPreference.Output.Verbosity = 'Detailed'
function Test-Path {$True} # hides the real Test-Path
function Get-FromShares($fromServer) {if ($fromServer -eq 'serverA') { @('ABshare1', 'ABshare2', 'ABshare3') } else {@('XYshare1', 'XYshare2', 'XYshare3')}}
function Get-ToShares($toServer) {if ($toServer -eq 'serverB') { @('ABshare1', 'ABshare2') } else {@('XYshare1', 'XYshare2')}}

class Shares { static $toShares = @{} }
function Test-Path {$True} # hides the real Test-Path
Describe "Describe" -ForEach @(
    @{fromServer ='serverA'; toServer = 'serverB'}    
    @{fromServer ='serverX'; toServer = 'serverY'}    
    ){

    #It "Define shares" -TestCases @( 1 )  { class Shares { static [string[]]$toShares = @('share1', 'share2') } }
    
    BeforeDiscovery {
        $fromShares = Get-FromShares($fromServer)
        [Shares]::toShares =@{ $fromServer = Get-ToShares($toServer)}
        $toShares = [Shares]::toShares[$fromServer]
        $readableFromShares = $fromShares | 
            Where-Object {$toShares -contains $_} | 
            Where-Object {Test-Path "\\$($fromServer)\$($_)"}
    }
     
    Context "<fromServer> samba shares should exist on <toServer>" { 
        BeforeAll {            
            $toShares = [Shares]::toShares[$fromServer]
        }
        It "Does \\<toServer>\<_> exist" -ForEach $fromShares {
            $toShares -contains $_ | Should -Be $true
        }
    }

    Context "Readable <fromServer> samba shares should als be readable on <toServer>" {
        It "<_> is readable on <fromServer>. \\<toServer>\<_> should also be readable." -ForEach $readableFromShares {
            Test-Path "\\$($toServer)\$($_)"| Should -Be $True
        }
    }
} 
4

2 回答 2

2

-foreach解决方案是使用您希望在It块中可用的任何数据来丰富传递给子句的变量。

在下面的示例中,$fromShares数组现在包含一个对象数组,而不是一个普通的字符串数组。每个对象仍然包含共享名称,还包含$toShares您在测试中需要的数组。


Describe "Describe" -ForEach @(
    @{fromServer ='serverA'; toServer = 'serverB'}    
    @{fromServer ='serverX'; toServer = 'serverY'}    
    ){
    
    BeforeDiscovery {
        $toShares = Get-ToShares($toServer)
        $fromShares = Get-FromShares($fromServer) | % {
            [PSCustomObject]@{
                fromShare = $_
                toShares = $toShares
            }
        }

        $readableFromShares = $fromShares | 
            Where-Object {$toShares -contains $_} | 
            Where-Object {Test-Path "\\$($fromServer)\$($_)"}
    }
     
    Context "<fromServer> samba shares should exist on <toServer>" { 
        BeforeAll {            
            $toShares = [Shares]::toShares[$fromServer]
        }
        It "Does \\<toServer>\<_.fromShare> exist" -ForEach $fromShares {
            $_.toShares -contains $_.fromShare | Should -Be $true
        }
    }

    Context "Readable <fromServer> samba shares should als be readable on <toServer>" {
        It "<_> is readable on <fromServer>. \\<toServer>\<_> should also be readable." -ForEach $readableFromShares {
            Test-Path "\\$($toServer)\$($_)"| Should -Be $True            
        }
    }
} 
于 2021-03-29T16:47:32.967 回答
1

我不熟悉纠缠,但我确实有一些建议:

Get-CimInstance使用从一个位置列出股票可能会有更好的运气(或速度) 。这是非纠缠代码:

# Discovery
$shares = $ServerNames | Foreach { Get-CimInstance –Class Win32_Share –ComputerName $_ }

# Run
# simple compare of the shares list between servers
$diff = Compare-Object -Property Name `
    -ReferenceObject  ($shares|where PSComputerName -Like $ServerA) `
    -DifferenceObject ($shares|where PSComputerName -Like $ServerB) `

# $diff should -eq $null

要测试它们是否都可读,请使用如下相同的内容$shares

foreach ($share in $shares) {
    It "\\$($share.PSComputerName)\$($share.Name) should be readable" {
        (Test-Path "\\$($share.PSComputerName)\$($share.Name)" -ea SilentlyContinue) | 
            Should -Be $True    
    }
}
于 2021-03-25T21:58:52.973 回答