Testing in PowerShell Powered by Pester NATHAN ZIEHNERT 5/25/2018.

Slides:



Advertisements
Similar presentations
11-Jun-14 The assert statement. 2 About the assert statement The purpose of the assert statement is to give you a way to catch program errors early The.
Advertisements

Module R2 CS450. Next Week R1 is due next Friday ▫Bring manuals in a binder - make sure to have a cover page with group number, module, and date. You.
Programming with Alice Computing Institute for K-12 Teachers Summer 2011 Workshop.
16-Jun-15 Exceptions. Errors and Exceptions An error is a bug in your program dividing by zero going outside the bounds of an array trying to use a null.
1 Introduction to Computers and Programming Quick Review What is a Function? A module of code that performs a specific job.
CIT 590 Unit testing. Agenda Debugging attempt 2 (because I am stubborn) What is unit testing Why? Unit testing framework in Python.
CPSC 252 Exception Handling Page 1 Exceptions and exception handling Client programmers can make errors using a class attempting to dequeue an item from.
Exceptions Handling Exceptionally Sticky Problems.
BIT 142:Programming & Data Structures in C#. What is Unit Testing? 2.
1.  “To write test cases for every non-trivial function or method in the module so that each test case is [as] separate from the others [as] possible.”
1.  Writing snippets of code that try to use methods (functions) from your program.  Each snippet should test one (and only one) function......by calling.
Hey, Ferb, I know what we’re gonna do today! Aims: Use formatted printing. Use the “while” loop. Understand functions. Objectives: All: Understand and.
Lecture 26: Reusable Methods: Enviable Sloth. Creating Function M-files User defined functions are stored as M- files To use them, they must be in the.
Scripting Languages Diana Trandab ă ț Master in Computational Linguistics - 1 st year
Introduction to Exceptions in Java CS201, SW Development Methods.
This was written with the assumption that workbooks would be added. Even if these are not introduced until later, the same basic ideas apply Hopefully.
JavaScript: Conditionals contd.
CMSC202 Computer Science II for Majors Lecture 16 – Exceptions
Advanced Programing practices
User-Written Functions
Excel IF Function.
Content Programming Overview The JVM A brief look at Structure
Chapter 6 CS 3370 – C++ Functions.
Data Types Variables are used in programs to store items of data e.g a name, a high score, an exam mark. The data stored in a variable is entered from.
CIT 590 Unit testing.
Introduction to Python
Handling Exceptionally Sticky Problems
Arrays: Checkboxes and Textareas
Exponents Scientific Notation
Turning Your Checklists
Functions CIS 40 – Introduction to Programming in Python
University of Washington Computer Programming I
Sentinel logic, flags, break Taken from notes by Dr. Neil Moore
MySQL - Creating donorof database offline
Exceptions 10-Nov-18.
Lecturer: Mukhtar Mohamed Ali “Hakaale”
Subroutines Idea: useful code can be saved and re-used, with different data values Example: Our function to find the largest element of an array might.
Exception Handling Chapter 9.
Conditions and Ifs BIS1523 – Lecture 8.
Sentinel logic, flags, break Taken from notes by Dr. Neil Moore
slides created by Ethan Apter
Coding Concepts (Sub- Programs)
Programming in JavaScript
Part B – Structured Exception Handling
We’re moving on to more recap from other programming languages
CMSC 202 Exceptions 2nd Lecture.
CMSC 202 Exceptions 2nd Lecture.
Coding Concepts (Basics)
Coding Concepts (Standards and Testing)
slides created by Ethan Apter
PowerShell Best Practices for SQL DBA’s
Coding Concepts (Data- Types)
Python programming exercise
Advanced Programing practices
Programming in JavaScript
CISC101 Reminders All assignments are now posted.
LONG MULTIPLICATION is just multiplying two numbers.
CMSC 202 Exceptions 2nd Lecture.
Handling Exceptionally Sticky Problems
Exceptions 10-May-19.
slides created by Ethan Apter and Marty Stepp
Michael Wall Senior DBA, Great Western Malting
CMSC 202 Exceptions 2nd Lecture.
Software Development Techniques
Switch Case Structures
Solving Absolute Value Equations
Unit Testing.
Presentation transcript:

Testing in PowerShell Powered by Pester NATHAN ZIEHNERT 5/25/2018

Happy GDPR Day!

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 https://blogs.technet.microsoft.com/heyscriptingguy/2015/12/14/what-is-pester-and-why- should-i-care/

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.

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.

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.

Demo Time!

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.

Demo Time!

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.

Questions?