Deep Equality with Pester

Yes and no.

It’s possible for an object to have infinite depth, if one of the depths contains an object referenced earlier in the tree, such as in the example below.

In this case, we could use shallow equality to avoid an infinite loop.

However, for the general case, we will want to trade our “shallow equality” functions for a “deep equality” function.

Deep EqualityDeep equality of all types“Deep equality” tests that every tier of our two objects are equivalent.

At every tier, we will not know the type of the objects we are testing nor will we know if they are even objects (as opposed to values).

As such, we will have to write a generic function for recursing our objects and returning whether our inputs are equivalent.

Writing a deep equality functionWe will need to write a recursive function: a function that calls itself.

Recursion is one of the major Functional Programming patterns.

Recursive functions consist of two parts:The Recursive Step that calls our recursive function (from within our recursive function)The Base Case that returns a valueIn our deep equality function,The Recursive Step is when we encounter a complex type and need to call our function on each item within the array or each property within the object/hashtable.

The Base Case is when we have either two objects of different types (that are therefore not equal) or when we have two values and we can return the simple equality check for those values.

Unlike our previous examples, this is a generic equality check function instead of a Pester assertion function, but we can easily use it in a Pester assertion:The Complete SolutionThe implementation above is just an example and has a few issues:It doesn’t contain all its dependenciesIt’s not woven with debugging codeIt is an internal helper function and not a “View” cmdlet — it does not have an expressive parameter interface or adhere to Verb-Noun namingIt doesn’t come with Pester testsInstead, use the Test-Equality cmdlet from the Functional module on PowerShell Gallery.

I highly encourage you to explore the module source on github, which contains other cmdlets you might find helpful for writing Pester tests, such as the Test-Any and Test-All cmdlets.

The best examples for leveraging these cmdlets in Pester tests is the module’s own Pester tests.

AppendixThese are some general problems and solutions I’ve observed with using Pester.

Feel free to comment if you’re having an issue that should be added here.

Why are my pester results stale?At the very top of every Pester script, you almost certainly import the module you’re testing.

Module imports only occur once in PowerShell, which is generally a good thing, as it means module initialization doesn’t have to be written to be idempotent, and it avoids a performance hit from subsequent imports.

However, you are probably running your Pester tests after every change to your module code, so in this rare case, you want to import the module every time your unit tests run.

If you’re unit testing your module with a simple file structure, you might prefer to avoid hard-coding the module name into the file.

Where did Pester go?If you recently moved from Windows PowerShell to PowerShell Core, you’re probably used to Pester being installed automatically and relying on a confusing command to update it.

Not anymore!.Just install Pester as you’d expect.

.. More details

Leave a Reply