This is a fairly new concept to me and all the code testing work I have done in my life has been done in the last year and using Pester. And must say forcing myself to write pester tests for every piece of code I cut has made me a better coder. More on that later. There are many kinds of tests you can write for your code but the one that every piece of code should not be without is unit testing. That is what I am going to be focusing on here in this post. Once you have a good understanding of writing unit tests you can take your automation framework to really amazing places by doing automated code quality, integration and infrastructure tests. But first thing first, you have to get familiar with unit testing.
Unit Testing Unit tests simply tests all the logic of your code and ensure what you expect to happen actually does. Keeping your unit tests in mind while coding will force you to write better code. When you call a function or go down a branch of code are the results returned of the type you were expecting? How many times was a particular CmdLet called, was this the expected amount given specific inputs? Creating proper tests for these things will ensure your code returns expected results and can be very helpful for ensuring that any future changes will work as designed. Unit testing does not ensure your code works! It only ensures that the logic is sound. This is something that will sink in after writing your first few dozen tests. It is still critically important to write solid unit tests.
Take your time Writing unit tests is not something that can be done quickly. Proper unit testing will add significant time to your development! Maybe twice as much time. It is also not unheard of that your unit testing scripts end up having more lines of code than the script it was written to test! This is a hard learned lesson and will be something that will take some getting used to, but definitely make an effort to write your unit tests in real time as you are developing your code! Try not to wait until the very end after you have written all your code otherwise you may spend days or weeks in a row doing nothing but writing unit tests and that can be mentally challenging.
So, is doing all this work worth it? Yes, unequivocally yes. It is an important point so I will say it again. Writing extensive unit testing simply forces you to write better code. There is no way around it. Also, I am of the belief that if you want to do a true self peer review of your code you can’t do it without writing proper and comprehensive unit testing. Writing unit tests for all logic branches of your code will uncover problems in your code that you may have been blind to while developing. Are you unsure you covered all logic branches of your code? Pester comes with CodeCoverage functionality to tell you exactly what lines in your code were and were not covered by your Pester tests. Make it a goal to strive for over 90% code coverage for all of your PowerShell scripts. It is a fair amount of work to get there, but again it is worth it.
Invoke-Pester -Script .\myAwesomeScript -CodeCoverage
Integration Testing In addition to unit testing there is integration testing. Where a unit test will address the logic in your code, integration testing will test the health of your data and infrastructure. Instead of pretending (or mocking) to test your results, integration tests could for example insert data into a database or retrieve live data and ensure what is returned is as expected. Integration testing is a completely separate level of testing and is completed independent from unit tests. But be sure to have your unit testing taken care of first before worrying integration testing. Keep integration testing on your backlog though, if for no other reason than its cool. :)
Automated and Enforce Testing
It is a good idea to integrate your testing standards into your continuous integration solution to ensure that any code that is being checked in has all the expected Pester tests in place, they all pass, and there is a minimum level of code coverage. Reject any commits that do not meet these thresholds. Taking steps to automate this can make your code review processes a bit more streamlined since the reviewers will not have to do extensive work reviewing pester tests and code coverage since your awesome continuous integration solution did that work already. Now the reviewers can focus on the important part of the code, the functionality and applicability.