Code Monkey home page Code Monkey logo

pester's Introduction

Pester

๐Ÿ’ต Please consider sponsoring nohwnd, fflaten or sponsoring Pester itself.

๐ŸŒต Documentation is available at https://pester.dev/docs/quick-start.

๐Ÿ“ฆ๐Ÿ” Pester is now signed. -SkipPublisherCheck should no longer be used to install from PowerShell Gallery on Windows 10.

๐Ÿ‘ฉ๐Ÿ‘จ We are looking for contributors! All issues labeled help wanted are up for grabs. They further split up into good first issue that are issues I hope are easy to solve. Bad first issue where I expect the implementation to be problematic or needs to be proposed and discussed beforehand. And the rest which is somewhere in the middle. If you decide to pick up an issue please comment in the issue thread so others don't waste their time working on the same issue as you. There is also contributor's guide that will hopefully help you.

Pester is the ubiquitous test and mock framework for PowerShell.

BeforeAll {
    # your function
    function Get-Planet ([string]$Name='*')
    {
        $planets = @(
            @{ Name = 'Mercury' }
            @{ Name = 'Venus'   }
            @{ Name = 'Earth'   }
            @{ Name = 'Mars'    }
            @{ Name = 'Jupiter' }
            @{ Name = 'Saturn'  }
            @{ Name = 'Uranus'  }
            @{ Name = 'Neptune' }
        ) | foreach { [PSCustomObject]$_ }

        $planets | where { $_.Name -like $Name }
    }
}

# Pester tests
Describe 'Get-Planet' {
  It "Given no parameters, it lists all 8 planets" {
    $allPlanets = Get-Planet
    $allPlanets.Count | Should -Be 8
  }

  Context "Filtering by Name" {
    It "Given valid -Name '<Filter>', it returns '<Expected>'" -TestCases @(
      @{ Filter = 'Earth'; Expected = 'Earth' }
      @{ Filter = 'ne*'  ; Expected = 'Neptune' }
      @{ Filter = 'ur*'  ; Expected = 'Uranus' }
      @{ Filter = 'm*'   ; Expected = 'Mercury', 'Mars' }
    ) {
      param ($Filter, $Expected)

      $planets = Get-Planet -Name $Filter
      $planets.Name | Should -Be $Expected
    }

    It "Given invalid parameter -Name 'Alpha Centauri', it returns `$null" {
      $planets = Get-Planet -Name 'Alpha Centauri'
      $planets | Should -Be $null
    }
  }
}

Save this code example in a file named Get-Planet.Tests.ps1, and run Invoke-Pester Get-Planet.Tests.ps1, or just press F5 in VSCode.

Learn how to start quick with Pester in our docs.

The example above also has an annotated and production ready version here.

Installation

Pester runs on Windows, Linux, MacOS and anywhere else thanks to PowerShell. It is compatible with Windows PowerShell 3, 4, 5, 6 and 7.

Pester 3 comes pre-installed with Windows 10, but we recommend updating, by running this PowerShell command as administrator:

Install-Module -Name Pester -Force

Not running Windows 10 or facing problems? See the full installation and update guide.

Features

Test runner

Pester runs your tests and prints a nicely formatted output to the screen.

test run output

Command line output is not the only output option, Pester also integrates with Visual Studio Code, Visual Studio, and any tool that can consume nUnit XML output.

Assertions

Pester comes with a suite of assertions that cover a lot of common use cases. Pester assertions range from very versatile, like Should -Be, to specialized like Should -Exists. Here is how you ensure that a file exists:

Describe 'Notepad' {
    It 'Exists in Windows folder' {
        'C:\Windows\notepad.exe' | Should -Exist
    }
}

Learn more about assertions in our documentation.

Mocking

Pester has mocking built-in. Using mocks you can easily replace functions with empty implementation to avoid changing the real environment.

function Remove-Cache {
    Remove-Item "$env:TEMP\cache.txt"
}

Describe 'Remove-Cache' {
    It 'Removes cached results from temp\cache.text' {
        Mock -CommandName Remove-Item -MockWith {}

        Remove-Cache

        Should -Invoke -CommandName Remove-Item -Times 1 -Exactly
    }
}

Learn more about Mocking here.

Code coverage

Pester can measure how much of your code is covered by tests and export it to JaCoCo format that is easily understood by build servers.

JaCoCo code coverage report

Learn more about code coverage here.

Build server integration

Pester integrates nicely with TFS, AppVeyor, TeamCity, Jenkins and other CI servers.

Testing your scripts, and all pull requests on AppVeyor is extremely simple. Just commit this appveyor.yml file to your repository, and select your repository on the AppVeyor website:

version: 1.0.{build}
image:
  - Visual Studio 2017
  - Ubuntu
install:
  - ps: Install-Module Pester -Force -Scope CurrentUser
build: off
test_script:
  - ps: Invoke-Pester -EnableExit

See it in action here! If you do not need to test your scripts against PowerShell Core, just simply remove the entire line mentioning Ubuntu.

Pester itself is built on AzureDevOps, and distributed mainly via PowerShell gallery.

Build Status latest version downloads

Further reading

Do you like what you see? Learn how to use Pester with our quick start guide.

Got questions?

Got questions or you just want to get in touch? Use our issues page or one of these channels:

Pester Twitter Pester on StackOverflow Testing channel on Powershell Slack Testing channel on Powershell Discord or try github discussions GitHub discussions.

Sponsored by

Pester is sponsored by Octopus Deploy.

Octopus deploy

As well as all the great folks on OpenCollective and GitHub.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. Contribute code.

Financial Contributors on Open Collective

Become a financial contributor and help us sustain our community. Contribute to Pester Open Collective.

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. Contribute

pester's People

Contributors

adbertram avatar alx9r avatar armaanmcleod avatar asears avatar bergmeister avatar brianbunke avatar bschwede avatar codito avatar dlwyatt avatar edharper01 avatar fflaten avatar fourpastmidnight avatar gnuechtel avatar indented-automation avatar it-praktyk avatar jameswtruher avatar jaykul avatar juneb avatar manojlds avatar mbergmann avatar mikeclayton avatar mrtns avatar mwrock avatar nohwnd avatar pcgeek86 avatar petseral avatar renehernandez avatar scottmuc avatar sethvs avatar thilas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pester's Issues

Mock: Not working when trying to mock PowerCLI (PSSnapin) functions

Specifically, Get-VMGuest, Get-View, and Get-Cluster

I may just not be setting up the hash table correctly.

    $GetVMGuest = @(
        @{
            OSFullName="Windows Server 2008 R2";
            Disks=@(
                @{
                    Path="C:\";
                    Capacity=32209104896;
                    FreeSpace=4992696320;
                },
                @{
                    Path="D:\";
                    Capacity=322091516565;
                    FreeSpace=4995656220;
                }
            )
        }
    )
    $GetView = @(
        @{
            Config=@{ Tools=@{ ToolsVersion=9113 } }
            Guest=@{
                ToolsStatus="toolsOk";
                IPAddress="192.168.1.1";
                HostName="example.example.com";
            }
        }
    )
    $GetCluster = @(
        @{
            Name="EXAMPLE-CLUSTER";
        }
    )

Mock Get-VMGuest { $GetVMGuest }
Mock Get-View { $GetView }
Mock Get-Cluster { $GetCluster }

The error message:

Get-VMGuest : Cannot process argument transformation on parameter 'VM'. Cannot convert the 
"System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type 
"VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]".
At D:\UserData\aaron\powershell\Functions\CollectVirtualServers.ps1:52 char:38
+                 $guest = Get-VMGuest $_
+                                      ~~
    + CategoryInfo          : InvalidData: (:) [Get-VMGuest], ParameterBindingArgumentTransfo 
   rmationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-VMGuest

Get-View : Cannot process argument transformation on parameter 'VIObject'. Cannot convert the 
"System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type 
"VMware.VimAutomation.Sdk.Types.V1.VIObject[]".
At D:\UserData\aaron\powershell\Functions\CollectVirtualServers.ps1:57 char:44
+                 $view = Get-View -VIObject $_
+                                            ~~
    + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingArgumentTransforma 
   tionException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-View

Get-Cluster : Cannot process argument transformation on parameter 'VM'. Cannot convert the 
"System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type 
"VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]".
At D:\UserData\aaron\powershell\Functions\CollectVirtualServers.ps1:63 char:44
+                 $cluster = Get-Cluster -VM $_
+                                            ~~
    + CategoryInfo          : InvalidData: (:) [Get-Cluster], ParameterBindingArgumentTransfo 
   rmationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-Cluster

The strange part is, I've mocked Connect-VIServer and Get-VM in the same test, and it seems to have no problems.

Not sure if it's related or not, but I'm also having to dot-source a certain function every time before I call Invoke-Pester or the session forgets it.

Mocking Write-Host

Could Pester internally be using Microsoft.PowerShell.Utility\Write-Host so we can Mock Write-Host? It's sometimes a little troublesome to create a wrapper function for Write-Host just to overcome this "problem"

Exceptions in Context should fail all tests in scope

If I have some code in the Context for setup purposes that fails, it would be great if the project would consider one of the two strategies below:

  1. Consider failing each It assertion/test with the same exception.
  2. Only report one error (relaying the fact that an error in the context setup failed)

Thoughts?

Example:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
. "$here\$sut"

Describe "SomeDescribe" {
  Context "When some Context runs and an error happens" {

      throw "some error during setup"

      It "Should report something" {
          # This test should not even run (but possibly fail with the error from the context setup)
      }
      It "Should report something else" {
          # This test should not even run (but possibly fail with the error from the context setup)
      }
    }
}

$val | should not benullorempty does not worth properly with empty function

When just starting a new fixture, the assert syntax has some VERY odd behavior. Given an empty function like so:

function Get-AppSetting {
}

The following test PASSES, and clearly should not:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
    $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
    . "$here\$sut"

    Describe "Get-AppSetting" -tag "WIP" {
            $val = Get-AppSetting $config "ClientValidationEnabled"
            It "should return the value if present" {
                $val | should not benullorempty
            }
    }

Should Not BeNullOrEmpty fails for Object arrays when they are not empty

Given the following test:

It "can use the Not BeNullOrEmpty assertion" {
    $item1 = New-Object PSObject -Property @{Id=1; Name="foo"}
    $item2 = New-Object PSObject -Property @{Id=2; Name="bar"}
    @($item1, $item2) | Should Not BeNullOrEmpty
}

I get the following output:

[-]   can use the Not BeNullOrEmpty assertion 2ms
   Expected: value to not be empty
   at line: 117 in C:\Projects\Pester2\Functions\Assertions\Should.Tests.ps1

Fix Pester function local variable scoping

Currently, local variables defined in Pester functions (e.g. $output in It) can be overridden in tests, resulting in erratic and unwanted behaviour.

We need to scope the local variables defined in Pester functions to private.

Pester "Should Throw" unreliable

Hey!

I came across a problem testing Exceptions.
When testing for exceptions it turns out to be unreliable and broken at some places. I put an example of it below for clarity!

----------------------------------------------------

I have 2 Methods:

function ThrowExceptionTest {
$Message = ("This Line should Throw an Exception")
Throw $Message
}

function DoesNotThrow {
}

----------------------------------------------------

The tests are:

It "should throw exception" {
ThrowExceptionTest | Should Throw
}

It "should throw exception 2" {
     Try {
        ThrowExceptionTest
        Write-Host -ForegroundColor Magenta "Exception not Thrown"
    } Catch 
    {
        Write-Host -ForegroundColor Magenta "Exception Thrown $($_.Exception)"
    }
}

It "should not throw Exception 1" {
    DoesNotThrow | Should Not Throw
}

It "should not throw Exception 2" {
    Try {
        DoesNotThrow
        Write-Host -ForegroundColor Magenta "Exception not thrown"
    } Catch {
       Write-Host -ForegroundColor Magenta "Exception $($_.Exception)" 
    }
}

The Output is:

----------------------------------------------------

[W0216 15:16:12 Temp\throw_test]> Invoke-Pester
Executing all tests in C:\Temp\throw_test
Describing ThrowExceptionTest
[-] should throw exception 1ms
This Line should Throw an Exception
at line: 8 in C:\Temp\throw_test\ThrowExceptionTest.Tests.ps1
Exception Thrown System.Exception: This Line should Throw an Exception
[+] should throw exception 2 6ms
[-] should not throw Exception 2ms
Expected: the expression to not throw an exception. Message was {The expression after '&' in a pipeline element produced a obje
ct that was not valid. It must result in a command name, script block or CommandInfo object.}
at line: 25 in C:\Temp\throw_test\ThrowExceptionTest.Tests.ps1
Exception not thrown
[+] should not throw Exception 0ms
Tests completed in 10ms
Passed: 2 Failed: 2

The troubling part is the error message:
Expected: the expression to not throw an exception. Message was {The expression after '&' in a pipeline element produced a obje
ct that was not valid. It must result in a command name, script block or CommandInfo object.}

Thanks,
Michael

PS: I have to admit that I have no clue which calls are valid and which aren't anymore as the documentation seems to be highly outdated and I haven't had the time to look at the SourceCode directly.

Have_Count_Of in docs

In the docs about Should it describes Have_Count_Of

C:\PS>$actual=@(1,2,3)
C:\PS>$actual | Should Have_Count_Of @(3,2) #Will fail

but when I run that in a test I get.

[-]    descriptive text here 155ms
     The term 'PesterHave_Count_Of' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
     at line: 32 in C:\Code\MyTest.Tests.ps1

Any thoughts?

Update wiki

There are some parts missing from the wiki as regards to examples and some things I think are wrong. Would it be an idea to go through the wiki and make it look better?
I can help out with some parts that I know of.

Fix .Net 3 Requirement

Windows 8 and PS 3 don't have .net 3 installed by default.

Change the PesterFailure.ps1 file not use a specific .net version. I assume specifying just -language CSharp runs on whatever framework is currently the powershell host.

So changing

Add-Type -language CSharpVersion3 @'

to

Add-Type -language CSharp @'

worked fine for me on Windows 8 without .net 3 installed, not sure if this breaks other platforms or not.

Powershell prompt is garbled by Invoke-Pester

My Powershell prompt gets "@{should=System.Object}" added to it when i run Invoke-Pester.

My test imports a module and calls functions from that. The functions contains Write-Host calls.

Using Invoke-Pester closes command line window

If you open a PS command-line, import Pester and invoke it on a set of valid tests, it will run the tests to correctly but close the window when the run is done. This behavior can be by commenting out the exit $failedTestCount line in the Exit-WithCode function of TestResults.

$pester.ShouldExceptionLine on occasion doesn't exist

Caveat: I can't imagine this hasn't been found by others so I suspect I am doing something wrong, however, there seems to be a problem (given my usage) with It.ps1.

If I throw an error in my test (mistakenly or intentionally), it appears that Get-PesterResult fails with the following errors:

Property 'ShouldExceptionLine' cannot be found on this object. Make sure that it exists.
At C:\Chocolatey\lib\pester.2.0.3\tools\Functions\It.ps1:124 char:12
+         if($pester.ShouldExceptionLine) {
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

The variable '$line' cannot be retrieved because it has not been set.
At C:\Chocolatey\lib\pester.2.0.3\tools\Functions\It.ps1:131 char:57
+         $failureLine = $test.StartPosition.StartLine + ($line-2)
+                                                         ~~~~~
    + CategoryInfo          : InvalidOperation: (line:String) [], RuntimeException
    + FullyQualifiedErrorId : VariableIsUndefined

The variable '$failureLine' cannot be retrieved because it has not been set.
At C:\Chocolatey\lib\pester.2.0.3\tools\Functions\It.ps1:132 char:44
+         $testResult.stackTrace = "at line: $failureLine in $($test.File)"
+                                            ~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (failureLine:String) [], RuntimeException
    + FullyQualifiedErrorId : VariableIsUndefined

I believe the problem is that on occasion (perhaps never?), ShouldExceptionLine is not set. To avoid this I changed the conditional in the if statement from simply

    ...
    if($pester.ShouldExceptionLine) {
        $line=$pester.ShouldExceptionLine
        $pester.ShouldExceptionLine=$null
    }
    ...

to

    ...
    if($pester.ContainsKey("ShouldExceptionLine") -and $pester.ShouldExceptionLine) {
        $line=$pester.ShouldExceptionLine
        $pester.ShouldExceptionLine=$null
    }
    ...

I suspect an additional modification would be to set ShouldExceptionLine (possibly in the catch block on line 76 of It.ps1, but I am not certain) as follows:

    ...
    try{
        temp
    } catch {
        $pester.results.FailedTestsCount += 1;
        if ($_.Exception | Get-Member Line) { $pester.ShouldExceptionLine = $_.Exception.Line }
        $exception = $_;
    }
    ...

I wonder if the problem is due to a Set-StrictMode -Version "Latest" or Set-StrictMode -Version 3 entry, perhaps that is why others haven't noticed this?

Thanks,
Mark

Easiest/recommended way to install pester

It would be useful to see on the Readme some instructions on how to get pester easily installed.

Currently I'm cloning the entire repo (new issue to follow) and then leveraging it that way.
I should be able to cinst pester. (it's up on chocolatey, but out of the gate doesn't appear to install in an easy way for me to leverage)

I would like to see a super-duper-happy-path to "run this, and boom you now have the pester module every time you run powershell" option.

Invoke-pester issues

Write script to validate the pester installation and also check whether pester is available in installed modules.
I need ps1 script ouput invoke-pester not installed means return false,otherwise return true

Testing dot sourced code that has functions with the same names as pester functions, hides the pester function

Testing a function that calls another function called "Cleanup" causes pester to call the dot sourced Cleanup and not its own Cleanup.

Not sure yet how to approach this. Whenever I think I finally understand powershell scoping rules, I am proved wrong. I just want to make sure we look at this because this had me spinning my wheels for quite some time before I realized what was happening.

Can't use break in for loop after Update-TypeData is called

After the System.Object type is extended in the Pester module, you can no longer break out of a loop construct using the break keyword in any code that follows. You receive the following exception:

@{should=System.Object}Invalid character '@', labels can only contain characters, numbers and '_'.
At [break statement location]
+    foreach($num in 1..1) { break <<<< }
...
...

You can reproduce if you modify your Pester.psm1 as follows:

function Invoke-Pester($relative_path = ".", [switch] $EnableExit) {
    Reset-GlobalTestResults
    . "$PSScriptRoot\ObjectAdaptations\PesterFailure.ps1"

    Write-Host "break works"
    foreach($num in 1..1) { break }

        Update-TypeData -pre "$PSScriptRoot\ObjectAdaptations\types.ps1xml" -ErrorAction SilentlyContinue

    Write-Host "break does not work"
    foreach($num in 1..1) { break }

    $fixtures_path = Resolve-Path $relative_path
    Write-Host Executing all tests in $fixtures_path
...
...

The error does not occur until the following line of code is executed:

Update-TypeData -pre "$PSScriptRoot\ObjectAdaptations\types.ps1xml" -ErrorAction SilentlyContinue

I'm still trying to figure out exactly what is causing the problem, but it looks like PowerShell is treating break as a variable (label) and fails when the type extensions execute. Just a guess though.

Edit

Found some more information. If you decorate your break statement with a loop label as described in the link below, the error does not appear. Maybe the @ character is being "defaulted" in when no label is specified? At any rate, it looks like Label is being extended with "should."

http://technet.microsoft.com/en-us/library/dd315285.aspx

Mocks declared in Describe are cleared at the end of the first context

Need to fiixup mock scoping. Ideally, you should be able to declare mocks global to a describe block within the describe and have all contexts inherit those with the option to override. This can make context "Arrange" sections much more clean. Alas, if there is more than one context, this fails unintuitively.

Build fails on Windows 8 and Windows 8.1

Tried to git clone from the repo, and then build. Got failed build with the following error:

Describing Setup
[-] returns a location that is in a temp area 3ms
Expected: {C:\Users\andrewsav\AppData\Local\Temp\pester}, But was {C:\Users\andrewsav\AppData\Local\Temp\pester}
at line: 7 in C:\Scm\pester\Functions\Setup.Tests.ps1

Tested both on Windows 8 and Windows 8.1 On Windows Server 2008R2 with powershell 3 it does not fail. The test script for some reason thinks that $env:Temp never has trailing slash.

Wrong line number is reported if fails not in main script file

It is possible that a test script invokes code from another file. When an exception is thrown from this another file, the line of code it happened on is reported incorrectly. This is because that the code assumes that it's always in the main test script file. It can be fixed by checking the current script file name and comparing it with the test script file name. I ended up doing something like this:

Start-PesterConsoleTranscript
try{
    temp
    "[+] $output " | Write-Host -ForegroundColor green;
} catch {
    $failure_message = $_.toString() -replace "Exception calling", "Assert failed on"

    $results.FailedTests += $name
    "[-] $output" | Write-Host -ForegroundColor red


    Write-Host -ForegroundColor red $error_margin$failure_message
    if ($_.InvocationInfo.ScriptName -eq "$TestDrive\temp.ps1") {
        $temp_line_number =  $_.InvocationInfo.ScriptLineNumber - 2
        $failure_line_number = $start_line_position + $temp_line_number
        Write-Host -ForegroundColor red $error_margin"Test script: $test_file"
        Write-Host -ForegroundColor red $error_margin"File: $($test_file): at line:$($failure_line_number)"
    }
    else {
        Write-Host -ForegroundColor red $error_margin"Test script: $test_file"
        Write-Host -ForegroundColor red $error_margin"File: $($_.InvocationInfo.ScriptName): at line:$($_.InvocationInfo.ScriptLineNumber)"
    }
}

Stop-PesterConsoleTranscript

I'm not sure if this is correct but this illustrates the idea.

How to call Invoke-Pester and get the results?

If I have a powershell build script and I want to call Invoke-Pester, how can I determine the exit status of the command?

I in change #18 the addition of the -ExitCode parameter, but when include this parameter it closes my powershell window. Not what I want...

How do I get a handle to the test results of Invoke-Pester? Something like '$LASTEXITCODE` will do, but even a Powershell object with more test results would be good.

Thoughts?

new-fixture command produces not working code

When running pester new-feature -Name bla, the code that is produced uses the legacy should syntax, and thus throws a error. The built-in help text also is not updated to explain the new syntax and still has it in format $true.should.be

Feature Request: Add support for handling exceptions

I would like to be able to test code that throws exceptions for known states/conditions.

As per Muc's suggestion, today, my test will have to look like this:

it "should throw some exception" {
    $exceptionThrown = $false
    try {
         Cmd-ThatThrowsCoolException
    } catch [My.CoolException] {
        $exceptionThrown = $true
    }

    $exceptionThrown.should.be($true)
}

But sytnax like this is MUCH better:

Context "when the system is in a weird state" {
   It -Throws CoolException {
       ...
   }
}

Wrong line number is reported if fails not in main script file

The line numbers is still out of wack in the latest nuget version (2.0.3). Powershell 3, Windows Server 2008 R2.

bla.Tests.ps1:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
    $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
    . "$here\$sut"

    Describe "bla" {

        It "does something useful" {
            Expect-Result $true $false "Stone flied"
        }
    }

bla.ps1:

# Empty
# Empty
# Empty
# Empty
# Empty
# Empty
# Empty
# Empty
# Empty
# Empty

function Expect-Result($expected, $actual, $text) {
    $actual | Should Be $expected
}

run pester, output is:

Executing all tests in C:\Andrew\pp\new-fixture
Describing bla
[-]   does something useful 192ms
   Expected: {True}, But was {False}
   at line: 18 in C:\Andrew\pp\new-fixture\bla.Tests.ps1
Tests completed in 192ms
Passed: 0 Failed: 1

The line number is apparently wrong.

Xml validation errors

This test is being ignored because it's returning validation errors. Previously this test was just asserting whether or not Validate-Xml returns $true or not. Since it's actually returning an array of validation errors, this test was passing resulting in a test that was passing when it shouldn't have been.

Function that uses a property fails test

I am trying to wrap a text fixture around some code that extends an object with a property. I get an error that appears to be caused by pester.

Has anyone succeeded in writing tests on functions that use properties?

The error I get:

Describing Get-PropertyOfItem
Select-Object : Property cannot be processed because property "should" already exists.
At C:\Repos\ClinicientOps\clinicientops\General\Functions\Get-PropertyOfItem.ps1:4 char:11
+     $files | Select-Object *, @{Name = "TestProperty"; Expression = { $dir.Length}} ...
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Windows:PSObject) [Select-Object], PSArgumentException
    + FullyQualifiedErrorId : AlreadyExistingUserSpecifiedPropertyNoExpand,Microsoft.PowerShell.Commands.SelectObjectC
   ommand

My function:

function Get-PropertyOfItem {
$dir = "C:\"
    $files = Get-ChildItem $dir
    $files | Select-Object *, @{Name = "TestProperty"; Expression = { $dir.Length}} -Last 1
    }

My test function:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
    $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".")
    . "$here\$sut"

    Describe "Get-PropertyOfItem" {

        It "does something useful" {

        $prop =     Get-PropertyOfItem
        $prop.TestProperty.should.be(3)
        }
    }

Failing pipelined should assertions report wrong line number in error

Here is an example that will illustrate this:

Describe "A line number mis calculation" {
    $someValue = "value"

    it "should be 'wrong'" {
        $someValue | should be 'wrong'
    }
}

The resulting pester failure is:

[-]   should be 'value' 101ms
   Expected: {wrong}, But was {value}
   at line: 49 in C:\dev\boxstarter\tests\pester.tests.ps1

Should be line 5 not 49.

Tagging describes

I would like to be able to tag describes to run a subset of tests...

I have fast and slow for instance.

Can describe maybe take a param?

Should Throw - need to expose error details

Given the following test

It "should not fail" {
    { throw 'helpful error message' } | Should Not Throw
}

I get the following output.

[-]   should fail 2ms
      Expected: the expression to not throw an exception
      at line: 9 in C:\Code\sample\powershellTests\src\run-sample.Tests.ps1

When an exception happens in a test, I would be helpful if we could see the actual exception. Currently the exception information appears to be swallowed and is hiding crucial details that would help us diagnose a failing test.

Similarly if we say "{ something } | Should Throw" I would be great if you could consider a syntax that would allow us to assert more specific information about the error.

Possibly something like

{ throw "hi"; } | Should Throw "hi"

Keeping in mind wild card or regex searches

{ [string]::Format("{0} {1}", "hello") } | Should Throw "*Index (zero based) must be greater than or equal to zero and less than the size of the argument list.*"

Or be able to determine the type of the exception object.

Mocking .NET Object Methods

Perhaps I just don't know how to accomplish this with the current Mock functionality, but here is an example:

    # This function sends an SMTP e-mail.
    # Set up the SMTP Connection object.
    $SMTPClient = New-Object System.Net.Mail.SMTPClient
    $SMTPClient.Host = "smtp.example.com"

    # Set up the mail message object.
    $MailMessage = New-Object System.Net.Mail.MailMessage
    $MailMessage.From = "[email protected]"
    $MailMessage.To = "[email protected]"
    $MailMessage.Subject = "This is the subject"
    $MailMessage.Body = "Example email."

    $SMTPClient.Send($MailMessage)

Is there any way to Mock the $SMTPClient.Send($MailMessage) method?

Test Time Elapsed should Measure Entire Describe

Currently the time measurements are around the It blocks. This is misleading since these are typically very simple comparisons of basic values and the bulk of the time is in the context or describe blocks. I suggest we measure the describes and print the times after each of those.

Dot Sourcing in test fixture not practical for all scripts

See SO question about this issue here: http://stackoverflow.com/questions/10540632/is-it-possible-to-include-functions-only-without-executing-the-script

A script such as the following is not we'll suited to be dot sourced in a test fixture because it has mandatory parameters and code not inside of functions that should not be executed but does get executed.

[cmdletbinding()]
param ( 
    [Parameter(Mandatory=$true)]
        [string] $MyInput
)

function Show-Input {
    param ([string] $Incoming)
    Write-Output $Incoming
}

function Save-TheWorld {
    #ToDo
}

Write-Host (Show-Input $MyInput)

Add Mocking capabilities

So I know I am not the first to ever think or mention this, but having done a deep dive into the Chocolatey testing written by @ferventcoder which uses pester and its own rolled mocks, I now have a picture in my head of how this might look. Something like this:

SYNTAX
Mock [-function <string>] [-mockWith <ScriptBlock>] [-paramFilter [<HashTable>]]
EXAMPLE
Describe "When calling Chocolatey-Install for return value" {
  $script:exec_chocolatey_install_actual = $true
  $expected='dude'
  Mock Chocolatey-Nuget -mockWith { return $expected} -paramFilter @{packageName={$packageName -eq 'testPackage'};version=$Pester.ANY}
  $returnv = Chocolatey-Install 'testpackage'

  It "should return appropriately" {
    $returnv.should.be($expected)
  }

  It "should return as the type that was passed in" {
    $true.should.be($returnv.GetType().Name -eq 'String')
  }  

}

The example uses one of the tests in Chocolatey. It is testing a function called Chocolatey-Install which in turn calls a function Chocolatey-Nuget. The test does not want the real Chocolatey-Nuget which does alot of internet stuff to actually run. The test just wants Chocolatry-Nuget to return the string 'dude' if Chocolatey-Nuget is called with a package name called 'testPackage'.

This would be implemented by Renaming the function called Chocolatey-Nuget to something else and then dynamically creating a function called Chocolatey-Nuget that invokes the mockWith scriptBlock if the param filters are met. At the end of Describe, all renamed mocked functions are renamed back to their original names.

I'd love to submit a pull request for this but wanted to get a discussion started.

Should.Be error - cannot call a method on a null-valued expression

I am trying to leverage pester and given the following steps I a not able to leverage the Should.Be(...) syntax of a test.

mkdir pester-issue
cd pester-issue
git init
git submodule add https://github.com/pester/Pester.git lib/pester
import-module .\lib\pester\Pester.psm1
New-Fixture src demoFunction
cd .\src

Edit the demoFunction.Tests.ps1 to look like

Describe "demoFunction" {

    It "should not fail" {
        "Hello".Should.Be("Hello")
    }
}

Save the test file and run the tests with the bin/pester.bat

..\lib\pester\bin\pester.bat

I get the following error

You cannot call a method on a null-valued expression.
at line: 12 in C:\Code\personal\pester-issue\src\demoFunction.Tests.ps1

Am I missing something?

Fix PsGet Url

The current url for installing via PsGet is looking at your personal GitHub repo, it has since moved to pester/pester

I supposed a simple submission request to PsGet would fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.