Foreword
Years ago, when I started writing PowerShell, I felt a spark. It was one of those sparks that get you excited to go to work. It was a spark that activated my inner geek and gave me an excellent sense of accomplishment after I had automated something. That spark has since turned into a fire which has energized practically my entire career. PowerShell is now a big part of my work life.
This is what Pester feels like. Thats big!
Pester is a product thats gotten me probably too excited sometimes and made my eyes light up with satisfaction when I see all of that lovely green output scrolling down the screen to confirm the success of my code.
As Ive worked with Pester over the years, I always performed a TDD-hybrid approach with it. TDD is writing failing tests first and then only writing the code that makes the tests pass. In a previous life, I was a Senior Automation Engineer using PowerShell, which, in a roundabout way, is the same thing as a PowerShell developer. I worked on code that provisioned test environments for my developers as well as code for projects for clients.
Before Pester, I would write thousands of lines of code, run it, fix it, run it, fix it, run it ad infinitum. It worked for the most part until some unknown bug crept in or someone else on my team made a change I wasnt expecting, and it would break. Id then have to dive in and spend time researching, fixing, and sometimes breaking other things in the process. At the time, I thought it was just how you wrote PowerShell code. I was wrong.
I thought that testingand thus Pesterwas a waste of time. Why would I want to essentially to write the same code again to confirm I wrote the code in the first place? To me, it was a huge time drain for little value. That is until I decided to buckle down and force myself not to write a single line of code that wasnt covered by a unit test.
This is my story.
One of the modules that I owned on my team was called EnvironmentManifest. This module was a home-grown PowerShell module that discovers all of the applications in a particular environment and builds XML manifests from them. It gathered the versions through DLL file versions, database queries, web service calls, and enumerating software installed on various servers. It then took all of this information and built a manifest from it. With this module, the user could compare these manifests over time to see the differences between different environments such as test, prod, etc. It was the most complicated module Id ever built.
It worked, but it was soon turning into a popular service that more people began using. I would receive lots of feature requests and bug reports and be expected to fix them. Every time a change request came in, I would cringe. Why? Because it was as fragile as Kanye Wests ego. It was like playing whack-a-mole every time I made a change. Id change something, and itd break somewhere else.
It was painful to maintain.
After dealing with this for many months, I decided to take the plunge and essentially rewrite it. I knew it would take weeks but, luckily, I have an understanding boss, and with this module now handling part of the SOX auditing process, it was critical. I had built a lot of tests before this, but this time I was going to get serious and write unit tests for everything. There wouldnt be a piece of this code that wasnt covered under a test!
So I began.
At first, it was frustrating as hell. I kept thinking to myself that this was such a waste of time and that it was taking me so long to get things done. But I continuedthirty or so tests in, my mindset began to change. Things started to click for me. That spark began to light. I cant put my finger on the exact moment, but at some point, I realized how nice it was to run a script to give a pass/fail. I tend to be an unorganized coder and, previously, I always had to get my mind on a new task as I switched around.
Now, where was I?
Did I leave this code in a workable state?
What was this function supposed to output again?
These questions didnt go through my head anymore. As I switched, I would get into the habit of running the test suite and immediately seeing the state of my code. There was no more racking my already tired brain trying to figure out where I was. The tests would tell me! It was like taking automation to the next level.
A couple of weeks in, I realized that coding this way was changing me. It was changing how I wrote code, changing my perception of taking too long and changing how I felt about my code. It was indeed a mind shift.
This mind shift made me realize that even though the time to get things done is much more significant, the confidence you have in your code increases dramatically. By building tests as you go along, you find bugs that you would never have caught by chance. You discover these bugs because writing tests force you to understand your code at another level. Youre compelled to analyze every decision youve made. Sometimes you realize a coding decision wasnt the best one to make in the first place.