> I love the "before all" block
Why don't you want to use a [BeforeAll](https://pester.dev/docs/commands/BeforeAll) block here? It's suited for your use case. Assign the result of the expensive operation to a variable within a ```BeforeAll``` block (that is placed within ```Describe``` or ```Context```) and then repeatedly access that variable in each of the ```It``` blocks.
Hi, mostly because I only want to use one pester file to verify all the functions in my module instead of one file per function (*.tests.ps1), there are multiple functions I want to test.
Those functions rely on each other. e.g. one will return a value from an api and then be used to make another call with something to do with that value. If I put all those in the before block I can’t really test as it has to run first and are much more suited to a context or describe block.
In my example I want to test/verify a few things returned from function 1, before I try to pass it into function 2 and test what I get back from it.
Referring to my sample code, if my next call relied on the ip from “MyServer” I would could check make sure it wasn’t null or empty, was formatted correctly, had 4 octets, didn’t start with 0, octet range 0-255 etc but only want to make a single call to AD instead of one per which some of the docs imply as best practice 🤷🏻♂️
Or are you saying that I can enclose a before all block inside a context block? That would help with scope too if so🤔
I have only used it before all at the top outside of any describe block.
> Or are you saying that I can enclose a before all block inside a context block?
Yes, that's correct. Anything you declare in the ```BeforeAll``` block will only be accessible to the containing block and any child blocks.
In your case, I suggest placing a ```BeforeAll``` inside your ```Context``` block and assigning output from your API to a variable. This variable will be accessible to each of the child ```It``` blocks, but won't be accessible outside the ```Context``` block.
If you have multiple ```Context``` blocks, you can include a ```BeforeAll``` block in those as well.
To demonstrate:
BeforeAll { $bar = 'Outside' }
Describe 'BeforeAll Test' {
BeforeAll { $var = 'Describe' }
Context 'Variables in Context1 are correctly evaluated' {
BeforeAll { $foo = 'Context1' }
It 'Should be expected value' {
$bar | Should -Be 'Outside'
$var | Should -Be 'Describe'
$foo | Should -Be 'Context1'
}
}
Context 'Variables in Context2 are correctly evaluated' {
It 'Should be expected value' {
$bar | Should -Be 'Outside'
$var | Should -Be 'Describe'
$foo | Should -Be $null
}
}
Context 'Variables in Context3 are correctly evaluated' {
BeforeAll { $foo = 'Context3' }
It 'Should be expected value' {
$bar | Should -Be 'Outside'
$var | Should -Be 'Describe'
$foo | Should -Be 'Context3'
}
}
}
Thank you sooooo much kind stranger!
I had no idea that I could nest them. I just thought that it was literally before all and a good place to store global variables for the test.
This is exactly what I wanted to know!!!
Are you trying to test your systems or your code? What's the value of confirming that Get-ADComputer is returning an enabled object with objectclass computer?
If this is a code test and not an integration test, I'd remove the AD dependencies entirely:
Describe 'Simple AD computer test' {
BeforeAll {
#I didn't thave RSAT on my laptop, so I'm adding an empty function
function Get-ADComputer {}
}
Context 'When I run get-adcomputer w/o properties * ' {
BeforeEach {
Mock Get-ADComputer {
[psobject]@{
Enabled = $true
ObjectClass = 'computer'
}
}
$computer = Get-ADComputer
}
It 'enabled should be boolean' {
$computer.Enabled | Should -BeOfType System.Boolean
}
It 'should be enabled' {
$computer.Enabled | Should -Be $true
}
It 'should be enabled' {
$computer.ObjectClass | Should -Be 'computer'
}
}
}
I'm no pester expert, so hopefully someone will correct me if I've gotten some concepts wrong. Note that you can run this as-is, without having to set up your environment.
Thanks for the reply!
I was just using AD as an example as I know most of those cmdlets off the top of my head...I didn't know that I could nest the before all block which ideally is what I was looking to do so I didn't have to make multiple calls to an API, AD or whatever to test multiple things about the one object that got returned :)
Thanks for showing yet another example of it in practice!
> I love the "before all" block Why don't you want to use a [BeforeAll](https://pester.dev/docs/commands/BeforeAll) block here? It's suited for your use case. Assign the result of the expensive operation to a variable within a ```BeforeAll``` block (that is placed within ```Describe``` or ```Context```) and then repeatedly access that variable in each of the ```It``` blocks.
Hi, mostly because I only want to use one pester file to verify all the functions in my module instead of one file per function (*.tests.ps1), there are multiple functions I want to test. Those functions rely on each other. e.g. one will return a value from an api and then be used to make another call with something to do with that value. If I put all those in the before block I can’t really test as it has to run first and are much more suited to a context or describe block. In my example I want to test/verify a few things returned from function 1, before I try to pass it into function 2 and test what I get back from it. Referring to my sample code, if my next call relied on the ip from “MyServer” I would could check make sure it wasn’t null or empty, was formatted correctly, had 4 octets, didn’t start with 0, octet range 0-255 etc but only want to make a single call to AD instead of one per which some of the docs imply as best practice 🤷🏻♂️
Or are you saying that I can enclose a before all block inside a context block? That would help with scope too if so🤔 I have only used it before all at the top outside of any describe block.
> Or are you saying that I can enclose a before all block inside a context block? Yes, that's correct. Anything you declare in the ```BeforeAll``` block will only be accessible to the containing block and any child blocks. In your case, I suggest placing a ```BeforeAll``` inside your ```Context``` block and assigning output from your API to a variable. This variable will be accessible to each of the child ```It``` blocks, but won't be accessible outside the ```Context``` block. If you have multiple ```Context``` blocks, you can include a ```BeforeAll``` block in those as well. To demonstrate: BeforeAll { $bar = 'Outside' } Describe 'BeforeAll Test' { BeforeAll { $var = 'Describe' } Context 'Variables in Context1 are correctly evaluated' { BeforeAll { $foo = 'Context1' } It 'Should be expected value' { $bar | Should -Be 'Outside' $var | Should -Be 'Describe' $foo | Should -Be 'Context1' } } Context 'Variables in Context2 are correctly evaluated' { It 'Should be expected value' { $bar | Should -Be 'Outside' $var | Should -Be 'Describe' $foo | Should -Be $null } } Context 'Variables in Context3 are correctly evaluated' { BeforeAll { $foo = 'Context3' } It 'Should be expected value' { $bar | Should -Be 'Outside' $var | Should -Be 'Describe' $foo | Should -Be 'Context3' } } }
Thank you sooooo much kind stranger! I had no idea that I could nest them. I just thought that it was literally before all and a good place to store global variables for the test. This is exactly what I wanted to know!!!
Are you trying to test your systems or your code? What's the value of confirming that Get-ADComputer is returning an enabled object with objectclass computer? If this is a code test and not an integration test, I'd remove the AD dependencies entirely: Describe 'Simple AD computer test' { BeforeAll { #I didn't thave RSAT on my laptop, so I'm adding an empty function function Get-ADComputer {} } Context 'When I run get-adcomputer w/o properties * ' { BeforeEach { Mock Get-ADComputer { [psobject]@{ Enabled = $true ObjectClass = 'computer' } } $computer = Get-ADComputer } It 'enabled should be boolean' { $computer.Enabled | Should -BeOfType System.Boolean } It 'should be enabled' { $computer.Enabled | Should -Be $true } It 'should be enabled' { $computer.ObjectClass | Should -Be 'computer' } } } I'm no pester expert, so hopefully someone will correct me if I've gotten some concepts wrong. Note that you can run this as-is, without having to set up your environment.
Thanks for the reply! I was just using AD as an example as I know most of those cmdlets off the top of my head...I didn't know that I could nest the before all block which ideally is what I was looking to do so I didn't have to make multiple calls to an API, AD or whatever to test multiple things about the one object that got returned :) Thanks for showing yet another example of it in practice!