Download presentation
Presentation is loading. Please wait.
Published byCamilla Jordan Modified over 6 years ago
1
Testing in PowerShell Powered by Pester NATHAN ZIEHNERT 5/25/2018
2
Happy GDPR Day!
3
Who Am I? Nathan Ziehnert Senior Lead Consultant at Catapult Systems
Windows 10, System Center, and EM+S Extremely Lazy Zealous about reducing manual work NOT a Pester Expert should-i-care/
5
Definitions Unit Test Integration Test Acceptance Test TDD/BDD
Unit Test – this is the smallest test that can be run. Imagine it as a single piece of a puzzle. In most cases this will probably be a function inside of your PowerShell script – you are putting data of some sort in and expecting data to be returned. Unit tests will come first in your testing pipeline – you want to make sure your individual puzzle pieces are shaped as you expect. It is important to note however that the test should be run WITHOUT external dependencies (Get-ADUser for example). Pester introduces the ability to “Mock” functions so that you don’t have to rely on, say setting up an AD environment to test the function that might include Get-ADUser. Integration Tests – this is where you take all of your puzzle pieces and test to make sure that they all fit together as a whole. You want to make sure your whole script is working as expected when all of the individual units have passed their tests. You shouldn’t be running integration testing in production – you’d want to run Integration testing in some sort of test or development environment. Acceptance Tests – these are pretty much the same thing as integration tests, however they’re run just after you deploy your code to production. Essentially validating that all the testing you did leading up to this point has not been for nothing. TDD/BDD – I won’t cover these in depth in this presentation. TDD is “Test Driven Development” and suggests that you actually write your tests before writing your functions. Writing tests is like writing comments – we all know we should do it but quite frankly we don’t do it as often as we should (or for some of us – ever). Since you know what behavior you will be expecting from your function or unit of code, you can write the test first based on the behavior and then write the function and test against it. This brings us to “Behavior Driven Deployment” – simplified it means write your tests to the behavior not to the result. So if you write a function that adds 1 to a number, you shouldn’t write a test that says the result will be “1” after the test is run – you’re now making an assumption that the starting point is zero! So instead write the test with the current value of the number and then the result being adding one to that number. It will become more clear when we show some examples.
6
Introducing Pester What is Pester? Do I care?
No. Really. I’m a SysAdmin, not a coder. Do I care? Microsoft and VMWare What is Pester? Pester is a testing framework for PowerShell. It allows you to write tests that you can perform against your code so that when you make changes to your code, you can be more certain that it will work in production. Do I care? Let’s put it this way – for short scripts, you probably don’t care. It’s a good habit to be in – just like leaving comments in your code is a good habit to be in. However, it is a valuable skill to have when it comes to being a PowerShell expert. I am seeing more and more references to Unit Testing and other development practices leaking over into the IT world. If you don’t learn it now – when will you? No. Really. I’m a SysAdmin, not a coder. Do I care? Quite frankly? You should. How many of you have a script that cleans up your stale records in Active Directory or some other complicated script that runs on a schedule in your production environment? If you ever needed to make changes to it, how would you test that those changes didn’t introduce unexpected behavior? When you go to fill out your change request, what are you putting in your CR regarding testing? (I ran it in production already and it seemed to work just fine?) Microsoft and VMWare – Here’s the deal – Microsoft and VMWare both saw so much value in Pester that instead of writing their own testing frameworks for PowerShell they are actively contributing to the Pester project instead. In addition to that Microsoft has included Pester as part of the installation of PowerShell in Windows 10.
7
Getting Started Describe Context It Should Not
Function MultiplyByTwo { param($input) return $input * 2; } Describe ‘My MultiplyByTwo Tests’{ Context ‘Number Tests’{ It ‘Multiplies Positive Numbers Properly’{ MultiplyByTwo 4 | Should Be 8 It ‘Multiplies Negative Numbers Properly’{ [int]$testInt = -4 MultiplyByTwo $ testInt | Should Be -8 Describe Context It Should Not The important thing to note about unit tests is that they’re designed to be human readable. Anytime you give a name to a one of the blocks, make it descriptive. Describe – Describe “describes” a group of tests. Any Pester test file must contain at least one Describe block and all other commands for Pester (with limited exceptions) must be placed inside this block. Context – Contexts are optional subgroups of tests inside Describe. Say you wanted to multiply something by two – well, you could multiply a string by two, you could multiply a number by two, and you could multiply an array by two. But multiplying a number could also include multiplying negative numbers, or even decimals – so maybe you want to group your number tests together in a context. It – this is a single test case. When you run Invoke-Pester, each it block will produce a pass/fail status. Scoping – Describe/Context/It are all script blocks – you can do anything inside of them that you would normally do in a script block including setting variables. They also follow the same rules for variable scoping – so a variable defined inside of an It block would not be accessible to the Context block, etc. Should – Should is an assertation. You are asserting that something is true. The basic operators are Be, BeExactly, and Throw. Be is non-case sensitive – but the values must be equal. BeExactly adds case sensitivity to string comparisons. Throw asserts that the test should produce a terminating error – and you can add an optional message (or part of a message) to the throw assertation to make sure that the right error was thrown. Not – Not can be added in front of any operator (Should Not Be) and it negates the result. Should not be $false would pass, whereas Should not be $true would fail.
8
Demo Time!
9
Mocking Mock Assert-MockCalled Mock Disable-ADAccount
Assert-MockCalled Disable-ADAccount –Times 0 function TestObject($value1, $value2){ $obj = New-Object PSCustomObject $obj | Add-Member –MemberType NoteProperty –Name ‘Value 1’ –Value $value1 $obj | Add-Member –MemberType NoteProperty –Name ‘Value 2’ –Value $value2 } Mock Get-MyObjects{ TestObject –value1 Name –value2 Nate TestObject –value1 Name –value2 Steve Mock Assert-MockCalled Mock – Mock allows you to temporarily replace the behavior of a PowerShell command with whatever you want it to be. Even nothing. Assert-MockCalled – Used in conjunction with mock, it allows you to validate how a command was called, or that it was called and the number of times. Times 0 asserts that it never runs, times n asserts that it runs at LEAST n times. If you need it to run exactly a certain number of times you can use the Exactly parameter instead. You have the option to filter which calls should be counted – so if you’re calling the same mock command multiple times you could filter it to check on a specific run case of that command.
10
Demo Time!
11
Gotchas Open curly braces have to be on the same line as describe, context, and it. InModuleScope Curly Braces – I’m a C# guy at heart… and all the functions that I write have curly braces on my second line, not on the same line as the function. InModuleScope – When you import a module, an additional scope is created for variables, functions, and what not separate from the caller of the module. So if you’re testing a module, you can wrap your test scripts into an “InModuleScope name” which will put the testing into the scope of the module as well so that the tests can be run against those modules.
12
Questions?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.