azurepowershellazure-devopsazure-pipelines-yamlpester

Pester Test Case giving error in BeforeDiscovery with null value


Whenever I am trying to use parameter value in BeforeDiscovery under Context in Pester test case it's giving below error. Please help me.

Error:: ##[error] [-] Discovery in D:\a\1\s\deploymenttest\deployment.Tests.ps1 failed with: ##[error] System.Management.Automation.ParameterBindingValidationException: Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. ---> System.Management.Automation.ValidationMetadataException: The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. ##[error] at System.Management.Automation.ValidateNotNullOrEmptyAttribute.Validate(Object arguments, EngineIntrinsics engineIntrinsics) ##[error] at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags) ##[error] at BeforeDiscovery, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 5749 ##[error] at , D:\a\1\s\deploymenttest\deployment.Tests.ps1: line 18 ##[error] at New-Block, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 807 ##[error] at Context, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 8258 ##[error] at , D:\a\1\s\deploymenttest\deployment.Tests.ps1: line 16 ##[error] at New-Block, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 807 ##[error] at Describe, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 9839 ##[error] at , D:\a\1\s\deploymenttest\deployment.Tests.ps1: line 14 ##[error] at , C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 3034 ##[error] at Invoke-File, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 3043 ##[error] at Invoke-BlockContainer, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 2942 ##[error] at Discover-Test, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 1468 ##[error] at Invoke-Test, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 2462 ##[error] at Invoke-Pester, C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1: line 5046 ##[error] at , D:\a_temp\154b6b5a-47a9-492f-9385-458fa30e1098.ps1: line 59 ##[error] at , : line 1

Here is my Powershell pester code.

param(
        [string]$environment
    )

BeforeDiscovery {
    $commonConfig = Import-PowerShellDataFile -Path .\parameters\common.psd1
}

BeforeAll {
    $rgConfig = Import-PowerShellDataFile -Path .\parameters\resourcegroup.psd1
}

Describe 'DevopsLab' {
    
    Context 'ResourceGroup' {

        BeforeDiscovery {
            $tmpTagList = (Get-AzResourceGroup -Name $rgconfig.$environment.rgname).Tags
            $tagList = @()

            foreach ($tagName in $tmpTagList.Keys) {
                $tagList += @{
                    name = $tagName
                    value = $tmpTagList.$tagName
                }
            }
        }


        It 'exists' {
            Get-AzResourceGroup -Name $rgconfig.$environment.rgname | Should -Not -BeNullOrEmpty
        }

        It 'all 3 tags are created' {
            (Get-AzResourceGroup -Name $rgconfig.$environment.rgname).Name
            (Get-AzResourceGroup -Name $rgconfig.$environment.rgname).Tags.Count | Should -BeGreaterOrEqual 3
        }

        it 'has an environment tag with value <environment>'{
            $envTagValue = (Get-AzResourceGroup -Name $rgconfig.$environment.rgname).Tags.Environment
            $envTagValue | Should -Be $environment
        }        
    }
}

Yaml Code::

        - task: AzurePowerShell@5
          displayName: Deployment Validation Test Status
          inputs:
            azureSubscription: SC-Partner
            ScriptType: InlineScript
            Inline: |
                Set-Location $(System.DefaultWorkingDirectory)
                New-Item $(System.DefaultWorkingDirectory)\TestResults.xml -ItemType File

                $container = New-PesterContainer -Path ./deploymenttest/deployment.Tests.ps1 -Data @{ environment='dev'}
                $pesterConfig = [PesterConfiguration]@{
                  Run = @{
                      Exit = $true
                      Container = $container
                  }
                  Output = @{
                      Verbosity = 'Detailed'
                  }
                  TestResult = @{
                      Enabled      = $true
                      OutputFormat = "NUnitXml"
                      OutputPath   = "TestResults.xml"
                  }
                  Should = @{
                      ErrorAction = 'Stop'
                  }
                }

Solution

  • The code in BeforeDiscovery is running during Discovery but the code in BeforeAll won't run until the Run phase. You are getting rgConfig in BeforeAll but consuming in BeforeDiscovery, during which time the value of rgConfig isn't available.

    Also, according to the Pester official doc Discovery and Run,

    Using variables set in BeforeAll in -TestCases (or -ForEach) won't work. The variable from BeforeAll simply won't be defined until much after -TestCases and -ForEach are evaluated.