In my previous posts, I explored how to develop, test, and publish Bicep modules for Azure Bicep Registry, and how to enhance compliance checks with PSRule. Now, we’re diving into using Pester - a versatile PowerShell testing framework - to write custom unit tests for Azure Bicep modules, complementing PSRule’s best-practice checks and giving more granular insights into your module configurations.

Why Add Pester Tests?

While PSRule is excellent for high-level compliance and best-practice validation, Pester enables you to write unit tests that target specific Bicep components. This allows you to verify individual properties, ensure default configurations, and test parameter handling, providing a deeper level of testing.

Key Benefits of Pester in Bicep Module Testing:

  • Granular Testing: Test individual properties like SKU types, parameter validation, and output values.
  • Immediate Feedback: Get quick feedback on changes during development, ensuring module quality before integration.
  • Custom Validation: Write tests that match your organization’s unique standards and requirements.

Setting Up Pester in Your DevOps Pipeline

  1. Create Pester Test Files: Place .ps1 files in your module’s test folder (/tests/pester) with specific tests for each module.

  2. Sample Pester Test Structure:

    Describe "Storage Account Module Tests" {
        Context "Parameter Validation" {
            It "Should use Standard_LRS for SKU" {
                $params = @{
                    skuName = 'Standard_LRS'
                    location = 'eastus'
                }
                $result = Test-BicepModule -Path './modules/storageAccount/main.bicep' -Params $params
                $result | Should -Contain 'Standard_LRS'
            }
        }
    
        Context "Output Verification" {
            It "Should return correct storage account ID" {
                $result = Get-BicepModuleOutput -Path './modules/storageAccount/main.bicep' -Params $params
                $result | Should -MatchRegex "^/subscriptions/.+/resourceGroups/.+/providers/Microsoft.Storage/storageAccounts/"
            }
        }
    }
    
  3. Add a Pester Job in Your Azure DevOps Pipeline: Incorporate the Pester job into your pipeline with these steps:

    - job: RunPesterTests
      displayName: "Run Pester Unit Tests for Bicep Module"
      pool:
        vmImage: 'windows-latest'
      steps:
        - task: PowerShell@2
          inputs:
            targetType: 'inline'
            script: |
              # Install Pester if not available
              if (-not (Get-Module -ListAvailable -Name Pester)) {
                Install-Module Pester -Force -Scope CurrentUser
              }
              Invoke-Pester -Script './modules/**/tests/pester' -OutputFormat NUnitXml -OutputFile './pester-results.xml'
    
  4. Integrate PSRule for Full Validation: Run PSRule checks after Pester tests to ensure that all best-practice and compliance guidelines are also met.

Conclusion

By combining Pester for targeted, detailed tests with PSRule for broader compliance checks, you create a more resilient, comprehensive testing suite for your Azure Bicep modules. This pipeline ensures your modules are not only configured correctly but also align with industry and organizational standards.