Comprehensive test suite using Pester 5.x with unit and integration tests.
Tests/
├── Unit/ # Unit tests for individual modules
│ ├── ConfigManager.Tests.ps1
│ └── TaskScheduler.Tests.ps1
├── Integration/ # Integration tests for end-to-end scenarios
│ └── Initialization.Tests.ps1
├── Fixtures/ # Test data and sample files
│ ├── sample_app_settings.json
│ └── sample_tasks.json
└── README.md
.\Invoke-Tests.ps1.\Invoke-Tests.ps1 -Tag Unit.\Invoke-Tests.ps1 -Tag Integration.\Invoke-Tests.ps1 -Tag Initialization
.\Invoke-Tests.ps1 -Tag ErrorHandling.\Invoke-Tests.ps1 -CI
# Generates TestResults.xml and coverage.xml.\Invoke-Tests.ps1 -Coverage $falseInvoke-Build Test
Invoke-Build TestUnit
Invoke-Build TestIntegrationInvoke-Build
# Runs: Clean -> Analyze -> Test -> BuildTests are tagged for easy filtering:
- Unit: Unit tests for individual functions
- Integration: End-to-end integration tests
- Initialization: Tests for app initialization system (Issues #2-#8)
- PathResolution: Tests for path resolution in PS2EXE
- ErrorHandling: Tests for error handling and recovery
- Encoding: UTF-8 encoding tests
- E2E: Complete end-to-end scenarios
# Install required modules
Install-Module -Name Pester -MinimumVersion 5.0 -Force -SkipPublisherCheck
Install-Module -Name PSScriptAnalyzer -Scope CurrentUser# Install all dependencies automatically
Invoke-Build InstallDependenciesCode coverage is enabled by default and covers:
src/Modules/ConfigManager.psm1src/Modules/TaskScheduler.psm1
Coverage reports are generated in JaCoCo format: coverage.xml
Target coverage: 80%+
#Requires -Modules Pester
BeforeAll {
Import-Module (Join-Path $PSScriptRoot '..\..\src\Modules\YourModule.psm1') -Force
}
Describe 'Your-Function' {
Context 'When condition X' {
It 'Should do Y' {
# Arrange
$input = 'test'
# Act
$result = Your-Function -Input $input
# Assert
$result | Should -Be 'expected'
}
}
}#Requires -Modules Pester
BeforeAll {
$script:RepoRoot = Join-Path $PSScriptRoot '..\..\'
}
Describe 'Feature Integration' -Tag 'Integration' {
Context 'When doing end-to-end operation' {
BeforeEach {
# Setup test environment
}
It 'Should complete full workflow' {
# Test complete feature flow
}
}
}The .github/workflows/test.yml workflow runs tests on every push and PR.
.\Invoke-Tests.ps1 -CI
# Mimics CI environmentThe Fixtures/ directory contains sample data files:
sample_app_settings.json: Sample application settingssample_tasks.json: Sample scheduled tasks
Use these in tests to avoid hardcoding test data.
Tests create temporary directories for isolation:
$testDir = Join-Path ([System.IO.Path]::GetTempPath()) "Test_$(New-Guid)"Always clean up in AfterAll blocks.
Invoke-Pester -Path Tests/Unit/ConfigManager.Tests.ps1 -Output DetailedInvoke-Pester -Path Tests/Unit/ConfigManager.Tests.ps1 -FullNameFilter "*Initialize-AppData*".\Invoke-Tests.ps1 -VerboseSome tests are marked -Skip for the following reasons:
- %TEMP% fallback test: Requires mocking
New-Itemwhich is complex in Pester 5- Will be implemented when fallback strategy is finalized (Issue #7)
- Windows Task Scheduler integration: Requires administrative privileges
- Covered in integration test suite with manual testing
- DailyMotivation.ps1 initialization: Depends on Issue #5 fix
- Error dialog tests: Cannot test UI dialogs in non-interactive context
- PS2EXE path resolution: Requires building EXE and testing
When fixing bugs or adding features:
- Add failing test first (TDD approach)
- Implement fix
- Verify test passes
- Update related integration tests
- Check code coverage (should not decrease)
All tests should:
- Have clear descriptive names
- Test one thing per
Itblock - Clean up after themselves
- Be independent (no shared state between tests)
- Run quickly (< 1 second per test for unit tests)
- CLAUDE.MD - Project conventions
- GitHub Issues #2-#8 - Initialization system fixes