使用 Pester 测试强制参数
Testing for mandatory parameters with Pester
我正在尝试弄清楚如何对缺少的参数进行 Pester 测试:
查找-Waldo.Tests.ps1
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
Describe 'Mandatory paramters' {
it 'ComputerName' {
{
$Params = @{
#ComputerName = 'MyPc'
ScriptName = 'Test'
}
. "$here$sut" @Params
} | Should throw
}
}
Find-Waldo.ps1
Param (
[Parameter(Mandatory)]
[String]$ComputerName,
[String]$ScriptName
)
Function Find-Waldo {
[CmdletBinding()]
Param (
[String]$FilePath
)
'Do something'
}
每次我尝试 assert
结果或只是 运行 测试时,它都会提示我输入 ComputerName
参数而不是让测试失败。
我是不是漏掉了一些非常明显的东西?有没有办法测试强制参数的存在?
根据 Mathias 的评论,您无法真正测试是否缺少 Mandatory 参数,因为 PowerShell 会提示输入它而不是抛出错误。根据 comment he linked to from the Pester team,您可以使用 Get-Command
来测试脚本中的强制参数设置(假设它是为该变量设置的唯一参数属性)
((Get-Command "$here$sut").Parameters['ComputerName'].Attributes.Mandatory | Should Be $true
另一种选择是在这种情况下不使用强制参数,而是使用一个脚本块来执行 Throw
作为参数的默认值:
Param (
[String]$ComputerName = $(Throw '-ComputerName is required'),
[String]$ScriptName
)
如果脚本始终用作自动化过程的一部分(而不是通过用户执行),这可能是首选,因为它允许您 control/capture 它的行为并避免它在执行过程中卡住。然后您可以按照最初的建议测试脚本:
Describe 'Mandatory paramters' {
it 'ComputerName' {
{
$Params = @{
#ComputerName = 'MyPc'
ScriptName = 'Test'
}
. "$here$sut" @Params
} | Should throw '-ComputerName is required'
}
}
虽然接受的答案表明这是不可能的,但实际上是可能的。这是我为解决这个问题而开发的解决方案。
It 'Should fail when no priority is specified, for a valid process name' {
{
$ScriptBlock = {
Import-Module -Name $args[0]
Set-ProcessPriority -Name System
}
Start-Job -ScriptBlock $ScriptBlock -ArgumentList $HOME/git/ProcessPriority/src/ProcessPriority | Wait-Job | Receive-Job
} | Should -Throw
}
您将从上面的示例中注意到:
正在测试的代码已包装在 PowerShell 中 ScriptBlock
我们调用包含测试代码的 PowerShell 后台作业
我们等待后台作业完成,然后接收结果
如果您 运行 Get-Job
命令,您会注意到 Blocked
状态
中有一个作业
后台作业抛出的异常类似如下:
The Wait-Job cmdlet cannot finish working, because one or more jobs are blocked waiting for user interaction. Process interactive job output by using the Receive-Job cmdlet, and then try again.
您会注意到我将文件系统路径硬编码到模块。我不确定如何将此作为参数传递给 Pester 为我们调用的 "outer" ScriptBlock
。也许有人对如何完成最后一块拼图有建议。
PowerShell 后台作业的独特之处在于,您实际上可以 恢复 处于 Blocked
状态的作业,它会提示您输入,即使它引发了较早的异常。
我正在尝试弄清楚如何对缺少的参数进行 Pester 测试:
查找-Waldo.Tests.ps1
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
Describe 'Mandatory paramters' {
it 'ComputerName' {
{
$Params = @{
#ComputerName = 'MyPc'
ScriptName = 'Test'
}
. "$here$sut" @Params
} | Should throw
}
}
Find-Waldo.ps1
Param (
[Parameter(Mandatory)]
[String]$ComputerName,
[String]$ScriptName
)
Function Find-Waldo {
[CmdletBinding()]
Param (
[String]$FilePath
)
'Do something'
}
每次我尝试 assert
结果或只是 运行 测试时,它都会提示我输入 ComputerName
参数而不是让测试失败。
我是不是漏掉了一些非常明显的东西?有没有办法测试强制参数的存在?
根据 Mathias 的评论,您无法真正测试是否缺少 Mandatory 参数,因为 PowerShell 会提示输入它而不是抛出错误。根据 comment he linked to from the Pester team,您可以使用 Get-Command
来测试脚本中的强制参数设置(假设它是为该变量设置的唯一参数属性)
((Get-Command "$here$sut").Parameters['ComputerName'].Attributes.Mandatory | Should Be $true
另一种选择是在这种情况下不使用强制参数,而是使用一个脚本块来执行 Throw
作为参数的默认值:
Param (
[String]$ComputerName = $(Throw '-ComputerName is required'),
[String]$ScriptName
)
如果脚本始终用作自动化过程的一部分(而不是通过用户执行),这可能是首选,因为它允许您 control/capture 它的行为并避免它在执行过程中卡住。然后您可以按照最初的建议测试脚本:
Describe 'Mandatory paramters' {
it 'ComputerName' {
{
$Params = @{
#ComputerName = 'MyPc'
ScriptName = 'Test'
}
. "$here$sut" @Params
} | Should throw '-ComputerName is required'
}
}
虽然接受的答案表明这是不可能的,但实际上是可能的。这是我为解决这个问题而开发的解决方案。
It 'Should fail when no priority is specified, for a valid process name' {
{
$ScriptBlock = {
Import-Module -Name $args[0]
Set-ProcessPriority -Name System
}
Start-Job -ScriptBlock $ScriptBlock -ArgumentList $HOME/git/ProcessPriority/src/ProcessPriority | Wait-Job | Receive-Job
} | Should -Throw
}
您将从上面的示例中注意到:
正在测试的代码已包装在 PowerShell 中 ScriptBlock
我们调用包含测试代码的 PowerShell 后台作业
我们等待后台作业完成,然后接收结果
如果您 运行 Get-Job
命令,您会注意到 Blocked
状态
后台作业抛出的异常类似如下:
The Wait-Job cmdlet cannot finish working, because one or more jobs are blocked waiting for user interaction. Process interactive job output by using the Receive-Job cmdlet, and then try again.
您会注意到我将文件系统路径硬编码到模块。我不确定如何将此作为参数传递给 Pester 为我们调用的 "outer" ScriptBlock
。也许有人对如何完成最后一块拼图有建议。
PowerShell 后台作业的独特之处在于,您实际上可以 恢复 处于 Blocked
状态的作业,它会提示您输入,即使它引发了较早的异常。