<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1678611822423757&amp;ev=PageView&amp;noscript=1">
Defrag This

| Read. Reflect. Reboot.

How to Use Tags in a PowerShell Pester Test

Adam Bertram| January 23 2019

| IT insights, PowerShell, Automation, Software Testing, Pester

how-to-use-tags-in-a-powershell-pester-test

One of Pester’s useful features is the Tags feature. A tag allows a developer to organize their tests based on different criteria and execute those tests accordingly. Tags allow a developer to manage large test suites that may take hours to run by only executing certain tests matching certain tags.

Pester, if you’re not familiar, is the de-facto unit-testing framework for PowerShell. It allows not just developers to create reliable, tested code in PowerShell. 

To demonstrate, let’s say that you’ve got a Pester test that tests the state of a Windows server. Perhaps you’ve got a PowerShell script that is supposed to create a new testing lab. This script creates a virtual machine, installs a Windows feature, and creates a few Active Directory users. The scenario can be anything really. The important point is that you have one or more environmental states you’d like to confirm.

Related: How To Create An Azure DevTest Lab

Let’s say you’ve confirmed that when a virtual machine called TEST-DC is online, that VM should have the AD-Domain-Services Windows feature installed and it should have a user called ‘abertram’ and a user called ‘dtrump’ created in that domain. You’d like to create some Pester tests for this scenario using tags.

First, you’d create some Pester tests using the familiar describe/it block syntax. Below I’ve created some dummy tests to give you an example of how a typical infrastructure test may be created. Notice that we have three “levels” of tests. We have the tests representing the creation of the VM, tests representing the set up of Active Directory on that VM and tests to confirm Active Directory is populated with the expected objects. What the tests are aren’t important, these various “levels” of tests are.

describe 'VM Creation' {

    it 'the TEST-DC VM should exist' {
        Get-VM -Name TEST-DC -ErrorAction Ignore | should not benullorempty
    }
}

describe 'Forest Provisioning' {

    it 'the Active Directory Windows feature should be installed on TEST-DC' {
        Get-WindowsFeature -ComputerName TEST-DC -Name 'AD-Domain-Services' | where { $_.Installed } | should not benullorempty
    }

}

describe 'Domain User Creation' {

    it 'the Active Directory forest should have the expected users created' {
        $users = Invoke-Command -ComputerName TEST-DC  -ScriptBlock {
            Get-AdUser -Filter * | where {$_.Name -in @('abertram','dtrump')}
        }
        $users.Count | should be 2
    }
}

Let’s say all of these tests are created in a file called C:.Tests.ps1. When these tests run using the Invoke-Pester command (Invoke-Pester -Path C:\TestDomain.Tests.ps1) all of the tests run at once. With only a single test in each describe block, that’s not a big deal but what if you’ve got hundreds of tests in here? It’s necessary to allow only a certain number of tests to execute at a time. To do this, can use tags!

If multiple people are working on different test phases, for example, it’d be handy to only execute the VM creation tests or the domain user creation tests by themselves. We can assign tags to each describe block and we can now choose which tests to run.

describe -Tag 'VM' 'VM Creation' {

    it 'the TEST-DC VM should exist' {
        Get-VM -Name TEST-DC -ErrorAction Ignore | should not benullorempty
    }
}

describe -Tag 'Active Directory Set Up' 'Forest Provisioning' {

    it 'the Active Directory Windows feature should be installed on TEST-DC' {
        Get-WindowsFeature -ComputerName TEST-DC -Name 'AD-Domain-Services' | where { $_.Installed } | should not benullorempty
    }

}

describe -Tag 'Active Directory Object Creation' 'Domain User Creation' {

    it 'the Active Directory forest should have the expected users created' {
        $users = Invoke-Command -ComputerName TEST-DC  -ScriptBlock {
            Get-AdUser -Filter * | where {$_.Name -in @('abertram','dtrump')}
        }
        $users.Count | should be 2
    }
}

With our tags added now, we can call Invoke-Pester -Path C:\TestDomain.Tests.ps1 -Tag 'VM' to only call the ‘VM’ tests or use the ‘Active Directory Set Up’ tags to only call those tests. Likewise, if we want to run all of our tests excluding tags, we can use the ExcludeTag parameter like `Invoke-Pester -Path C:\TestDomain.Tests.ps1 -ExcludeTag 'VM'.

pester

Pester tags are a simple concept but a great way to organize large test suites. They allow quick testing, a separation of tests based on a user-defined methodology as I’ve done here and are a great way for multiple people to run tests from the same script without stomping on each others’ toes.

Topics: IT insights, PowerShell, Automation, Software Testing, Pester

Leave a Reply

Your email address will not be published. Required fields are marked *

THIS POST WAS WRITTEN BY Adam Bertram

Adam Bertram is a 20-year veteran of IT. He’s currently an automation engineer, blogger, independent consultant, freelance writer, author, and trainer. Adam focuses on DevOps, system management, and automation technologies as well as various cloud platforms. He is a Microsoft Cloud and Datacenter Management MVP and efficiency nerd that enjoys teaching others a better way to leverage automation.

Free Trials

Getting started has never been easier. Download a trial today.

Download Free Trials

Contact Us

Let us know how we can help you. Focus on what matters. 

Send us a note

Subscribe to our Blog

Let’s stay in touch! Register to receive our blog updates.