标签: pester

如何在PowerShell中进行TDD和单元测试?

随着MS对所有新服务器产品进行攻击,我开始(不情愿地)认为我需要认真对待它."认真对待"的部分内容是TDD.你有没有找到好的单元测试电源shell脚本的方法?

我找到了Geek Noise先生的嘲笑样本- 但我真的很喜欢像RhinoMocks这样的东西.Brian Hartsock有一个从MS Test对powershell字符串运行测试的示例.有点hacky,但它似乎工作.

我想要的是Powershell TDD体验,它与"真实"语言一样干净.


更新澄清:

前两个答案试图引导我远离测试Powershell.意见很有趣.我不想知道在PowerShell中测试是否是个好主意.这是一个主观问题,应该在不同的论坛上提出.我想要一个单元测试PowerShell的解决方案.如果您认为这是一个坏主意(可能是这样),请将其视为一个有趣的学术问题.

  • 是的,脚本语言将不同的系统粘合在一起.但是,正如已经指出的那样,用动态语言模拟和破坏接缝也很容易.
  • 我不是在问"调试".调试是一个非常有用的主题.我会让别人问它.
  • 也许PS脚本应该很简单.该语言支持模块化,复杂的过程将不可避免地在PS中实现(即使是一个坏主意).
  • 这个问题的答案不是"你不能".我可以看到(来自链接的博客 - 有点老),有些人在这个问题上取得了进展.

重新声明:如何以xUnit的方式实现Powershell逻辑的自动测试? 集成测试很有趣,单元测试打破了最有趣的依赖关系.

tdd powershell unit-testing pester

66
推荐指数
2
解决办法
1万
查看次数

确定PSCustomObject的数组是否包含具有属性值的实例

我需要确定一个PSCustomObjects 数组是否包含一个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)

有更好的选择吗?

powershell powershell-3.0 pester

13
推荐指数
1
解决办法
1万
查看次数

Pester可以嘲笑一个例外吗?

我正在研究一些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)

powershell unit-testing mocking try-catch pester

8
推荐指数
1
解决办法
1656
查看次数

从内部模拟脚本块访问外部变量(Pester)

假设我有一个类似的功能...

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 块中的预期结果进行硬编码。关于如何实现这一目标有什么想法吗?

powershell pester

8
推荐指数
2
解决办法
1362
查看次数

在Pester中进行模拟时,如何使用switch参数来使用parameterFilter?

使用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)

无济于事.

powershell pester

7
推荐指数
2
解决办法
2200
查看次数

有人在Powershell中使用BDD吗?

我在stackoverflow找到了很多围绕这个问题的线程.他们现在已经2岁了.所以我想知道是否有人使用scottmuc函数在PowerShell中执行BDD.乍一看似乎非常强大.

你有什么看法?有人知道其他一些有效的BDD框架吗?我想要一些非常接近rspec的东西.

注意我需要BDD而不是TDD(PSUnit)建议/指示.


在powershell上没有多少人使用BDD,看到答案:).这是否意味着BDD完全没用,只是因为PowerShell只是脚本编写?我认为这不是一个正当理由.

无论如何这里的列表到目前为止:

  • Pester,更接近像rspec这样的东西
  • PowerSpec,似乎只是少数几个should

bdd powershell pester

6
推荐指数
1
解决办法
1077
查看次数

Powershell的单元测试框架

3年前有一个问题涉及Powershell单元测试框架,如何在 PowerShell 中进行TDD和单元测试?,那时所有的框架都是新的:

3年后,我认为他们已经进化并变得成熟.现在我想做TDD(从未做过),我不知道使用哪一个.在Internet上搜索,看起来PSUnit和Pester是最常用的.

你在用它们吗?他们每个人的利弊是什么?任何推荐?

谢谢,

powershell unit-testing psunit pester

6
推荐指数
0
解决办法
555
查看次数

如何使用 PowerShell 多线程并通过 Pester Mocks 进行单元测试

我正在尝试在 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)

powershell multithreading mocking pester

6
推荐指数
1
解决办法
666
查看次数

Pester 没有捕捉到抛出的错误

当我运行以下纠缠测试时,我希望它能够捕获预期的错误,但它没有。但是,当我使用不同的 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)

powershell pester

6
推荐指数
1
解决办法
2888
查看次数

如何在Pester中模拟一份工作?

我们正试图评估是否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

powershell mocking pester

6
推荐指数
1
解决办法
350
查看次数