Status: Accepted Date: 2025-10-18 Deciders: Paweł Żentała, Claude (Solution Architect)
We need a robust testing framework for oh-my-pwsh to ensure code quality, prevent regressions, and enable safe refactoring. PowerShell has several testing options, but we need to choose one that balances functionality, community support, and ease of use.
- Must support unit, integration, and E2E tests
- Must have mocking capabilities
- Must generate code coverage reports
- Must integrate with CI/CD (GitHub Actions)
- Must be actively maintained
- Should be PowerShell-native (not a port of another framework)
We will use Pester 5.x as our primary test framework.
Specifically:
- Version: Pester 5.5.0 or later
- Installation: Via PowerShell Gallery (
Install-Module Pester) - Scope: All test types (unit, integration, E2E)
- Mature & Stable: Pester is the de-facto standard for PowerShell testing (10+ years)
- Built-in Mocking: Native support for
Mock,InModuleScope,Should -Invoke - Code Coverage: Built-in coverage analysis via
-CodeCoverageparameter - CI/CD Integration: Well-documented integration with GitHub Actions, Azure DevOps
- Large Community: Extensive documentation, examples, StackOverflow support
- PowerShell Native: Written in PowerShell, understands PowerShell semantics
- Assertions: Rich assertion library (
Should -Be,Should -Throw, etc.) - JUnit XML: Generates test reports compatible with CI systems
- Learning Curve: Pester 5.x has different syntax than 4.x (migration needed if upgrading)
- Breaking Changes: v4 → v5 was a breaking change (but we start fresh)
- Performance: Can be slow for very large test suites (mitigated by parallelization)
- Mocking Limitations: Some advanced mocking scenarios are tricky
- Windows-First: While cross-platform, some features work better on Windows
- Dependency: Adds external dependency (but acceptable for dev/CI)
- Version Management: Need to ensure Pester version consistency across environments
- Pros: Simpler syntax, faster for small suites
- Cons: Abandoned (last update 2016), no mocking, no coverage
- Verdict: ❌ Not maintained
- Pros: Full control, tailored to our needs
- Cons: Reinventing the wheel, maintenance burden, no community
- Verdict: ❌ Overkill
- Pros: Already commonly used, catches static issues
- Cons: Not a test framework, no runtime testing, no coverage
- Verdict: ❌ Complementary tool, not a replacement
- Pros: Older, more examples online
- Cons: Deprecated, no new features, slower
- Verdict: ❌ Superseded by Pester 5.x
# Install Pester 5.x
Install-Module -Name Pester -MinimumVersion 5.5.0 -Force -SkipPublisherCheck
# Verify version
Get-Module Pester -ListAvailableBeforeAll {
# Load module under test
. $PSScriptRoot/../../modules/status-output.ps1
}
Describe "Write-StatusMessage" {
Context "When given a simple string message" {
It "Should output the message with icon" {
# Arrange
Mock Write-Host {}
# Act
Write-StatusMessage -Role "success" -Message "Test"
# Assert
Should -Invoke Write-Host -Times 4 # icon, brackets, message
}
}
}$config = [PesterConfiguration]::Default
$config.CodeCoverage.Enabled = $true
$config.CodeCoverage.Path = "modules/*.ps1"
$config.CodeCoverage.OutputFormat = "JaCoCo"
Invoke-Pester -Configuration $config- 005-testing-infrastructure.md - Implementation task
- TESTING-STRATEGY.md - Overall testing strategy
- TESTING-GUIDE.md - How to write tests (to be created)