2

We are writing Pester test for testing the Azure Resource group to contain certain tags. Following is the script and unfortunately the Pester test is not reporting any failure even after a particular resource group we are checking doesn't contain some of the Tags (from the Array defined). The Pester tests just passes and I am not sure what is that we are doing wrong here.

$resourceGroupName ='DemoRG03032021' 

$listOfTags = @('BUSINESS-OWNER','COST-CENTER','LIFECYCLE1', 'APPLICATION','PROJECT-CODE','TECHNICAL-OWNER','BUDGET-CODE')

$checkTags = $false

Describe "Resource Group" {
    Context "$resourceGroupName" { 
        $resourceGroup = Get-AzResourceGroup -Name $resourceGroupName

        foreach ($tagName in $listOfTags)
        {
             It "$($resourceGroup.ResourceGroupName) has a $tagName as tag" {  

                $resourceGroup.tags.keys -contains $tagName | Should -Be $true
            }
        }
    } 
}
double-beep
  • 5,031
  • 17
  • 33
  • 41
user42012
  • 722
  • 12
  • 33
  • 3
    Which Pester version? In case it is 5 or higher, you probably need to put the variables along with `$listOfTags` in a [`BeforeAll`](https://pester-docs.netlify.com/docs/commands/BeforeAll) block. – iRon Mar 12 '21 at 07:33
  • Thank you @iRon I had to add BeforeDiscovery since I am using the For loop and Pester 5+ version. Apprecaite your help as you pointed on using BeforeAll and thats where I stumbled upon the BeforeDiscovery to be used. Thank you! – user42012 Mar 12 '21 at 14:21

1 Answers1

1

In v5 you can now also do it like this which is a bit more readable in my opinion:

BeforeDiscovery {
    $listOfTags = @('BUSINESS-OWNER', 'COST-CENTER', 'LIFECYCLE1', 'APPLICATION', 'PROJECT-CODE', 'TECHNICAL-OWNER', 'BUDGET-CODE')
}

BeforeAll { 
    $resourceGroupName = 'DemoRG03032021' 
    $resourceGroup = Get-AzResourceGroup -Name $resourceGroupName
}
    
Describe "Resource Group" -ForEach $listOfTags {
    It "$($resourceGroup.ResourceGroupName) has a $_ as tag" {  
        $resourceGroup.tags.keys -contains $_ | Should -Be $true
    }
} 

Edit: Putting the answer to your follow up question here as it's a lot more readable.

This is how I would personally organize the code you posted in the comments. I think adding another logical block makes sense, actually. If you put your other It statements inside of the block running with -Foreach then you would run every new test once for every tag in $listOfTags as well which is probably not what you want.

BeforeDiscovery {
    $listOfTags = @('BUSINESS-OWNER', 'COST-CENTER', 'LIFECYCLE1', 'APPLICATION', 'PROJECT-CODE', 'TECHNICAL-OWNER', 'BUDGET-CODE')
}

Describe "Resource Group Tests" {

    BeforeAll { 
        $resourceGroupName = 'TestResourceGroup203122021' 
        $resourceGroupLocation = 'eastus22222' 
        $resourceGroup = Get-AzResourceGroup -Name $resourceGroupName 
    } 

    Context "Resource Group Tags" -ForEach $listOfTags { 
        It "$($resourceGroup.ResourceGroupName) has a $_ as tag" { 
            $resourceGroup.tags.keys -contains $_ | Should -Be $true 
        } 
    }

    Context "Resource Group Attributes" { 
        It "Resource Group $($resourceGroup.ResourceGroupName) Exists" { 
            $resourceGroup | Should -Not -BeNullOrEmpty 
        } 

        It "$($resourceGroup.ResourceGroupName) Location is $resourceGroupLocation" { 
            $($resourceGroup.Location) | Should -Be $resourceGroupLocation 
        } 
    }
}

Here is another way to think about it. If you wrote the following:

Foreach ($tag in $listOfTags){
   Write-Host 'do this thing for each tag'
   Write-Host 'do this thing once'
}

Imagine each Write-Host is your It statement. You don't want that second statement inside of the same context as the other, because you don't want it to run once for every value in $listOfTags. You logically separate it with a new Describe or Context block.

Efie
  • 1,430
  • 2
  • 14
  • 34
  • Thank you @Efie I think your solution is much more elegant and I agree readable and not only that actually my solution is not working as for every test in the For loop its returning false (Failure) which is not correct. But I used your code and it is working perfectly. One more question I had is what if I had 2 more tests to be included in the same Pester script, do I have to create another DESCRIBE block or I can use the same? Sorry if this sounds basic Q but I am very new to Pester. – user42012 Mar 13 '21 at 00:18
  • No dumb questions. There actually isn't a lot of stuff on Stack for v5 so the more stuff out there the better I think. You can add as many It blocks inside of describe as you want. It's a hierarchy so Describe -> Context -> It. You can then run setup in BeforeAll {} for everything in certain contexts and then do a different setup for another context of tests. In your case you could add another test as long as it has to do with that same $listOfTags group. Otherwise you want to split them up into context blocks. I'm running out of room but feel free to message me if you want – Efie Mar 13 '21 at 00:33
  • To clarify a little - if you add another It block it will run that test for every item in $listOfTags because Describe '...' -Foreach is saying run every nested It block for every item in that collection. – Efie Mar 13 '21 at 00:35
  • Thank you @Efi I appreciate your detailed response. Following is what I came up with and its working, athough I feel 2 describe blocks are not needed: BeforeAll { $resourceGroupName = 'TestResourceGroup203122021' $resourceGroupLocation = 'eastus22222' $resourceGroup = Get-AzResourceGroup -Name $resourceGroupName } Describe "Resource Group Tags" -ForEach $listOfTags { It "$($resourceGroup.ResourceGroupName) has a $_ as tag" { $resourceGroup.tags.keys -contains $_ | Should -Be $true } } – user42012 Mar 13 '21 at 00:49
  • Ran out of space so continuing here the 2nd describe block:-- Describe "Resource Group Attributes" { It "Resource Group $($resourceGroup.ResourceGroupName) Exists" { $resourceGroup | Should -Not -BeNullOrEmpty } It "$($resourceGroup.ResourceGroupName) Location is $resourceGroupLocation" { $($resourceGroup.Location) | Should -Be $resourceGroupLocation } } – user42012 Mar 13 '21 at 00:50
  • Above code is working with no issues, but I just feel like I am overdoing it with 2 describe blocks and things can work in one single Describe block but I am struggling with the Foreach and the single tests – user42012 Mar 13 '21 at 00:52
  • Thank you so much @Efie for your help! this is perfect I will use the above code format for future tests. Appreciate your detailed response and super quick help! – user42012 Mar 13 '21 at 14:07