Pester 5 变量范围问题 - BeforeDiscovery/It
Pester 5 variable scoping issue - BeforeDiscovery/It
编辑
问题的症结在于:如何访问 BeforeDiscovery
块中声明的 It
块中未被 [=15= 传递的变量]构造?
我很难适应 Pester 5 中的 Discovery/Run 阶段和变量范围
背景
我们正在移动服务器,我要测试的是
serverA
上的每一股在 serverB
上也 存在 。
- 在
serverA
上的每个 可读 分享在 serverB
上也是 可读。
使用 Pester 5,下面的代码按预期运行,但要使其正常工作,我必须检索 $toShares
两次。在我的实际测试中检索共享是使用 net view
并且是一个相当长的 运行 操作。
- 我必须在发现阶段检索
$toShares
以构建 $readableFromShares
列表
- 我必须在 BeforeAll 块中检索相同的
$toShares
才能在 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
}
}
}
输出 包括两次故意失败的测试
编辑
测试用例包括
- 两个 from/to 服务器(一个)
- 每组服务器的不同共享名
测试
$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
}
}
}
我对 pester 不熟悉,但我有一些建议:
使用 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
}
}
解决方案是使用您希望在 It
块中可用的任何数据来丰富传递给 -foreach
子句的变量。
在下面的示例中,$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
}
}
}
编辑
问题的症结在于:如何访问 BeforeDiscovery
块中声明的 It
块中未被 [=15= 传递的变量]构造?
我很难适应 Pester 5 中的 Discovery/Run 阶段和变量范围
背景
我们正在移动服务器,我要测试的是
serverA
上的每一股在serverB
上也 存在 。- 在
serverA
上的每个 可读 分享在serverB
上也是 可读。
使用 Pester 5,下面的代码按预期运行,但要使其正常工作,我必须检索 $toShares
两次。在我的实际测试中检索共享是使用 net view
并且是一个相当长的 运行 操作。
- 我必须在发现阶段检索
$toShares
以构建$readableFromShares
列表 - 我必须在 BeforeAll 块中检索相同的
$toShares
才能在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
}
}
}
输出 包括两次故意失败的测试
编辑
测试用例包括
- 两个 from/to 服务器(一个)
- 每组服务器的不同共享名
测试
$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
}
}
}
我对 pester 不熟悉,但我有一些建议:
使用 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
}
}
解决方案是使用您希望在 It
块中可用的任何数据来丰富传递给 -foreach
子句的变量。
在下面的示例中,$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
}
}
}