[英]Pester 5 variable scoping issue - BeforeDiscovery/It
Edit编辑
The crux of the question is: how do I get access to variable(s) declared in a BeforeDiscovery
block in my It
blocks that are not passed through by the it -foreach $var
construct?问题的症结在于:如何访问
It
块中未通过it -foreach $var
构造传递的BeforeDiscovery
块中声明的变量?
I'm having difficulties adjusting to the Discovery/Run phase and Scoping of Variables in Pester 5我很难适应 Pester 5 中的发现/运行阶段和变量范围
Background背景
We are moving servers and what I'm trying to test is我们正在移动服务器,我要测试的是
serverA
also exists on serverB
. serverB
上的每个共享也存在于serverA
上。serverA
is also readable on serverB
. serverB
上的每个可读共享在serverA
上也是可读的。 Using Pester 5, below code runs as intented but to make it work, I have to retrieve the $toShares
twice.使用 Pester 5,下面的代码按预期运行,但要使其正常工作,我必须检索
$toShares
两次。 Retrieving the shares in my actual tests is using a net view
and is a fairly long running operaton.在我的实际测试中检索共享是使用
net view
,并且是一个相当长的运行操作。
$toShares
in the Discovery phase to construct the $readableFromShares
list$toShares
以构建$readableFromShares
列表$toShares
in a BeforeAll block to have them available in the should exists
test$toShares
才能使它们在should exists
的测试中可用Question问题
How can I best restructure my test so that I only need to retrieve the $toShares
once?我怎样才能最好地重组我的测试,以便我只需要检索一次
$toShares
?
Testcode测试代码
$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
}
}
}
Output including two deliberate failing tests Output包括两个故意失败的测试
Edit编辑
Testcase including测试用例包括
Test测试
$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
}
}
}
The solution is to enrich the variables passed to the -foreach
clauses with whatever data you like to have available in the It
blocks.解决方案是使用您希望在
It
块中可用的任何数据来丰富传递给-foreach
子句的变量。
In below example, the $fromShares
array now contains an array of objects instead of a plain array of strings.在下面的示例中,
$fromShares
数组现在包含一个对象数组,而不是一个普通的字符串数组。 Each object still contains the share name and also contains the $toShares
array you need in your test.每个 object 仍然包含共享名称,还包含您在测试中需要的
$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
}
}
}
I'm not familiar with pester, but I do have some suggestions:我不熟悉纠缠,但我确实有一些建议:
You may have better luck (or speed) using Get-CimInstance
to list the shares from one location.您可能有更好的运气(或速度)使用
Get-CimInstance
从一个位置列出共享。 Here's non-pester code for that:这是非纠缠代码:
# 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
And to test if they're all readable, use the same $shares
something like this:并测试它们是否都可读,使用相同的
$shares
像这样:
foreach ($share in $shares) {
It "\\$($share.PSComputerName)\$($share.Name) should be readable" {
(Test-Path "\\$($share.PSComputerName)\$($share.Name)" -ea SilentlyContinue) |
Should -Be $True
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.