Nohwnd

Explore articles and content from this author

Nohwnd

1 article published

6 min read

Command and query separation in Pester tests

Do you feel that writing tests is confusing, and you often end up with complicated test code? I did too, before I learned about Command-query separation principle (or CQS). This principle lead me to start thinking about data flow directions in tests and in the end I realized there are few basic patterns that I use in my test code over and over.

Command-query separation principle

The command and query separation principle tells us that we should separate commands from queries (duh!). To do that, we first need to learn the difference between a command and query: A command is a function that has an observable side-effect and returns no result. A query is the opposite. A function that has no observable-side effect, and returns a result.
https://gist.github.com/nohwnd/fb5616fb92995555480c
The call to Set-Variable has a side effect of creating a variable named “a” and setting it to value “1”. This side effect is clearly observable, because we had no variable $a before the call and now we have one, so Set-Variable must be a command. Also the Set-Variable does not return any output which should be another clue (unless you provide the -PassThru parameter, more on that later).
The other call, the call to Get-Variable, has no observable side effect. You could call it once or 100 times and that would have no effect on the value of the $a variable. Plus the Get-Variable returns a result so it must be a query.
PowerShell also gives us another clue whether a function is a command or query with the Verb used for that function. Anything with Set, Add and New verb is supposed to be a command. Anything with Get verb should be a query.
Understanding the difference between commands and queries is important, because data flows through them in opposite directions, and so you need to test them differently.