随着MS对所有新服务器产品进行攻击,我开始(不情愿地)认为我需要认真对待它."认真对待"的部分内容是TDD.你有没有找到好的单元测试电源shell脚本的方法?
我找到了Geek Noise先生的嘲笑样本- 但我真的很喜欢像RhinoMocks这样的东西.Brian Hartsock有一个从MS Test对powershell字符串运行测试的示例.有点hacky,但它似乎工作.
我想要的是Powershell TDD体验,它与"真实"语言一样干净.
更新澄清:
前两个答案试图引导我远离测试Powershell.意见很有趣.我不想知道在PowerShell中测试是否是个好主意.这是一个主观问题,应该在不同的论坛上提出.我想要一个单元测试PowerShell的解决方案.如果您认为这是一个坏主意(可能是这样),请将其视为一个有趣的学术问题.
重新声明:如何以xUnit的方式实现Powershell逻辑的自动测试? 集成测试很有趣,单元测试打破了最有趣的依赖关系.
我需要确定一个PSCustomObject
s 数组是否包含一个Title
属性与值匹配的项.我需要一个布尔值来与Pester断言一起使用:
$Items -<function> $Name | Should Be $True
Run Code Online (Sandbox Code Playgroud)
假设:
$Items = @()
$Items += [PsCustomObject]@{Title='foo';Url='http://f.io'}
$Items += [PsCustomObject]@{Title='bar';Url='http://b.io'}
Run Code Online (Sandbox Code Playgroud)
Contains
不起作用:
PS> $Items -contains 'foo'
False
Run Code Online (Sandbox Code Playgroud)
Match
返回匹配的实例,但它不是布尔值:
PS> $Items -match 'foo'
Title Url
----- ---
foo http://f.io
Run Code Online (Sandbox Code Playgroud)
我想我可以:
($Items -Match $Name).Count | Should Be 1
Run Code Online (Sandbox Code Playgroud)
有更好的选择吗?
我正在研究一些Pester测试用例,我正在查看CodeCoverage结果.在大多数测试用例集中,我们的代码包含try/catch,我们在catch上获得0%的覆盖率.这是一个例子:
function Test-Is64Bit()
{
$Result = $false
try
{
if ((Get-WmiObject -Class "Win32_OperatingSystem").OSArchitecture -eq '64-bit')
{
$Result = $true
}
}
catch
{
Write-Error $_.Exception | Format-List -Force
}
return $Result
}
Run Code Online (Sandbox Code Playgroud)
模拟Get-WmiObject返回值以测试$ true条件非常容易.
我已经尝试了一些想法来模拟Get-WmiObject中的异常但是在每种情况下异常都会传递到控制台而不是被Pester捕获并通过测试.以下是我提出的最好的但它仍然不起作用.
Context "Unit tests for Get-WmiObject exception" {
# mock the Get-WmiObject cmdlet for unit testing
Mock Get-WmiObject {
Throw
} -ParameterFilter { $Class -And $Class -eq 'Win32_OperatingSystem' }
It "Function test passes" {
{ Test-Is64Bit } | Should Be $false
Assert-MockCalled Get-WmiObject -Scope It -Exactly …
Run Code Online (Sandbox Code Playgroud) 假设我有一个类似的功能...
function Get-Something {
return Get-DogShit
}
Run Code Online (Sandbox Code Playgroud)
...在我的 Pester 测试脚本中...
$var = 1
Mock 'Get-Dogshit' { return $var }
it 'should return true' {
Get-Something | should $var
}
Run Code Online (Sandbox Code Playgroud)
这行不通,但是你明白我在这里想做什么吗?我想将局部变量的值获取到 MOCK 脚本块中。我想避免对模拟中的返回值和 it 块中的预期结果进行硬编码。关于如何实现这一目标有什么想法吗?
使用Pester,我正在嘲笑一个高级功能,其中包括一个开关.如何-parameterFilter
为包含switch参数的mock 创建一个?
我试过了:
-parameterFilter { $Domain -eq 'MyDomain' -and $Verbose -eq $true }
-parameterFilter { $Domain -eq 'MyDomain' -and $Verbose }
-parameterFilter { $Domain -eq 'MyDomain' -and $Verbose -eq 'True' }
Run Code Online (Sandbox Code Playgroud)
无济于事.
我在stackoverflow找到了很多围绕这个问题的线程.他们现在已经2岁了.所以我想知道是否有人使用scottmuc函数在PowerShell中执行BDD.乍一看似乎非常强大.
你有什么看法?有人知道其他一些有效的BDD框架吗?我想要一些非常接近rspec的东西.
注意我需要BDD而不是TDD(PSUnit)建议/指示.
在powershell上没有多少人使用BDD,看到答案:).这是否意味着BDD完全没用,只是因为PowerShell只是脚本编写?我认为这不是一个正当理由.
无论如何这里的列表到目前为止:
3年前有一个问题涉及Powershell单元测试框架,如何在 PowerShell 中进行TDD和单元测试?,那时所有的框架都是新的:
3年后,我认为他们已经进化并变得成熟.现在我想做TDD(从未做过),我不知道使用哪一个.在Internet上搜索,看起来PSUnit和Pester是最常用的.
你在用它们吗?他们每个人的利弊是什么?任何推荐?
谢谢,
我正在尝试在 Powershell 中执行简单的并行操作。我正在使用 PoshRSJobs 进行多线程处理,尽管我也尝试过 Invoke-Parallel 来解决同样的问题。我需要在作业的脚本主体中调用几个我自己的函数,但这不允许我模拟这些函数以进行单元测试(它们最终成为原始的非模拟函数)。此时,我只是想断言它们被调用的次数是正确的。
这是原始类(导入模块的功能无关 - 实际实现当前返回测试字符串)...
Import-Module $PSScriptRoot\Convert-DataTable
Import-Module $PSScriptRoot\Get-History
Import-Module $PSScriptRoot\Get-Assets
Import-Module $PSScriptRoot\Write-DataTable
function MyStuff (
param(
[string]$serverInstance = "localhost\SQLEXPRESS",
[string]$database = "PTLPowerShell",
[string]$tableName = "Test"
)
$assets = Get-Assets
$full_dt = New-Object System.Data.DataTable
$assets | Start-RSJob -ModulesToImport $PSScriptRoot\Convert-FLToDataTable, $PSScriptRoot\Get-FLHistory {
$history = Get-History $asset
$history_dt = Convert-DataTable $history
return $history_dt.Rows
} | Wait-RSJob | Receive-RSJob | ForEach {
$full_dt.Rows.Add($_)
}
Write-DataTable $serverInstance $database $tableName $full_dt
}
Run Code Online (Sandbox Code Playgroud)
这是 Pester 测试...
$here = Split-Path -Parent $MyInvocation.MyCommand.Path …
Run Code Online (Sandbox Code Playgroud) 当我运行以下纠缠测试时,我希望它能够捕获预期的错误,但它没有。但是,当我使用不同的 throw 语句使用不同的函数运行测试时,它会起作用。
纠缠测试:
Describe "Remove-GenericCredential Function Tests" {
$InternetOrNetworkAddress = 'https://PesterTestUser@PesterTestURl.com'
Context "Test: Remove-GenericCredential -InternetOrNetworkAddress '$InternetOrNetworkAddress' (Credential does not exist)" {
It "This Command threw an error. The credential does not exist." { { (Remove-GenericCredential -InternetOrNetworkAddress $InternetOrNetworkAddress -Confirm:$false) } | should throw "Remove-GenericCredential : Credential $InternetOrNetworkAddress not found" }
}
}
Run Code Online (Sandbox Code Playgroud)
未捕获的错误:
Remove-GenericCredential : Credential https://PesterTestUser@PesterTestURl.com not found
At C:\Users\klocke7\Documents\WindowsPowerShell\Modules\Ford_CredentialManager\Tests\Remove-GenericCredential.Tests.ps1:30 char:76
+ ... xist." { { (Remove-GenericCredential -InternetOrNetworkAddress $Inter ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException …
Run Code Online (Sandbox Code Playgroud) 我们正试图评估是否Invoke-Command
已经被称为一次.
Script.ps1
Get-Job | Remove-Job
Invoke-Command -ScriptBlock {'test'} -ComputerName localhost -AsJob
Wait-Job
Get-Job | Reveive-Job
Run Code Online (Sandbox Code Playgroud)
Script.Tests.ps1
Describe 'Test' {
Mock Invoke-Command {
# Mock here
}
It 'should be green' {
."$here\$sut" @Params
Assert-MockCalled -CommandName Invoke-Command -Times 1 -Exactly -Scope It
}
}
Run Code Online (Sandbox Code Playgroud)
问题是在Pester中模拟工作对象.当作业未被模拟时,Wait-Job
将抛出一个未收到作业对象的错误.
如何模拟PowerShell作业对象Pester
?