Functions/GenXdev.Coding.PowerShell.Modules/_AssertGenXdevUnitTests.ps1
################################################################################ <# .SYNOPSIS Executes Pester unit tests for specified PowerShell modules. .DESCRIPTION This function runs Pester unit tests for PowerShell modules with configurable output settings. It can test specific modules or cmdlets, filter out unwanted modules, and control the verbosity of test results and stack traces. .PARAMETER BaseModuleName Specifies the base module name pattern to filter which modules to test. Accepts wildcards such as "GenXdev*" to match multiple modules. .PARAMETER ModuleFilter Optional filter to exclude modules that match the specified patterns. Any modules matching these patterns will be skipped during testing. .PARAMETER CmdletName Name of a specific cmdlet to test. If specified, only tests this cmdlet. Allows focused testing of individual cmdlets. .PARAMETER NoLocal When specified, excludes local development modules from testing. .PARAMETER OnlyPublished When specified, only tests modules that have been published. .PARAMETER FromScripts When specified, includes script modules in the testing process. .PARAMETER Verbosity Controls the detail level of test output. Valid values: None, Normal, Detailed, Diagnostic .PARAMETER StackTraceVerbosity Controls the amount of stack trace information shown in test results. Valid values: None, FirstLine, Filtered, Full .EXAMPLE _AssertGenXdevUnitTests -BaseModuleName "GenXdev.Helpers" -Verbosity Detailed ` -StackTraceVerbosity Full -NoLocal .EXAMPLE _AssertGenXdevUnitTests "GenXdev*" -CmdletName "Get-Something" -Verbose #> [CmdletBinding()] param ( ############################################################################ [Parameter( Mandatory = $false, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "Filter to apply to module names" )] [ValidateNotNullOrEmpty()] [Alias("Module", "ModuleName")] [ValidatePattern("^(GenXdev|GenXde[v]\*|GenXdev(\.\w+)+)+$")] [string[]] $BaseModuleName = @("GenXdev*"), ############################################################################ [Parameter( Mandatory = $false, HelpMessage = "Filter for selecting modules" )] [string[]] $ModuleFilter = $null, ############################################################################ [Parameter( Mandatory = $false, Position = 1, HelpMessage = "Filter for select cmdlets" )] [Alias("Filter", "CmdLet", "Cmd", "FunctionName", "Name")] [string] $CmdletName, ############################################################################ [Parameter( Mandatory = $false, HelpMessage = "Exclude local development modules" )] [switch] $NoLocal, ############################################################################ [Parameter( Mandatory = $false, HelpMessage = "Only test published modules" )] [switch] $OnlyPublished, ############################################################################ [Parameter( Mandatory = $false, HelpMessage = "Include script modules" )] [switch] $FromScripts, ############################################################################ [Parameter( Mandatory = $false, Position = 2, HelpMessage = "Sets the output verbosity level" )] [ValidateSet("None", "Normal", "Detailed", "Diagnostic")] [string] $Verbosity = "None", ############################################################################ [Parameter( Mandatory = $false, Position = 3, HelpMessage = "Controls stack trace information detail" )] [ValidateSet("None", "FirstLine", "Filtered", "Full")] [string] $StackTraceVerbosity = "FirstLine" ) begin { # store current location to restore it later $originalLocation = (Microsoft.PowerShell.Management\Get-Location).Path Microsoft.PowerShell.Utility\Write-Verbose "Original location saved: $originalLocation" # initialize results tracking $results = $null } process { try { # ensure consistent test execution location Microsoft.PowerShell.Utility\Write-Verbose "Setting location to solution root" Microsoft.PowerShell.Management\Set-Location "$PSScriptRoot\..\..\..\..\.." # process single cmdlet test if specified if (-not [string]::IsNullOrWhiteSpace($CmdletName)) { Microsoft.PowerShell.Utility\Write-Verbose "Processing single cmdlet test for: $CmdletName" # locate the specified cmdlet $cmdlet = GenXdev.Helpers\Get-GenXDevCmdlets -CmdletName $CmdletName | Microsoft.PowerShell.Utility\Select-Object -First 1 if ($null -eq $cmdlet) { Microsoft.PowerShell.Utility\Write-Warning "Cmdlet $CmdletName not found" return } Microsoft.PowerShell.Core\Import-Module -Name ($cmdlet.BaseModule) -Force # verify test file exists $testFilePath = $cmdlet.ScriptTestFilePath if (-not (Microsoft.PowerShell.Management\Test-Path $testFilePath)) { Microsoft.PowerShell.Utility\Write-Warning "No test file found at $testFilePath" return } # configure single test execution # initialize pester configuration Microsoft.PowerShell.Utility\Write-Verbose "Initializing Pester configuration" $config = Pester\New-PesterConfiguration $config.Output.Verbosity = $Verbosity $config.Output.StackTraceVerbosity = $StackTraceVerbosity $config.Run.Exit = $true $config.Run.PassThru = $true $config.TestResult.Enabled = $true $config.TestResult.OutputFormat = "NUnitXml" $config.Output.RenderMode = "Ansi" # $config.Run.TestExtension = "*.Tests.ps1" # Add this line to only match *.Tests.ps1 files $config.Run.Path = $null $config.TestResult.Enabled = $false $config.Run.Container = @( Pester\New-PesterContainer -Path $testFilePath ) Microsoft.PowerShell.Utility\Write-Verbose ("Running tests for cmdlet $CmdletName from file " + "$testFilePath") # execute tests $results = Pester\Invoke-Pester -Configuration $config # output results @($results) | Microsoft.PowerShell.Core\ForEach-Object -ErrorAction SilentlyContinue { $_ } } else { # copy parameters for module iteration $invocationParams = GenXdev.Helpers\Copy-IdenticalParamValues ` -FunctionName "GenXdev.Helpers\Invoke-OnEachGenXdevModule" ` -BoundParameters $PSBoundParameters # process all modules . GenXdev.Helpers\Invoke-OnEachGenXdevModule @invocationParams -Script { param($module) try { # apply module filters if ($null -ne $ModuleFilter) { foreach ($filtr in $ModuleFilter) { if ($module.Name -like $filtr) { Microsoft.PowerShell.Utility\Write-Verbose "Skipping filtered module $($module.Name)" return } } } # configure test settings # initialize pester configuration Microsoft.PowerShell.Utility\Write-Verbose "Initializing Pester configuration" $config = Pester\New-PesterConfiguration $config.Output.Verbosity = $Verbosity $config.Output.StackTraceVerbosity = $StackTraceVerbosity $config.Run.Exit = $true $config.Run.PassThru = $true $config.TestResult.Enabled = $true $config.TestResult.OutputFormat = "NUnitXml" $config.Output.RenderMode = "Ansi" # $config.Run.TestExtension = "*.Tests.ps1" # Add this line to only match *.Tests.ps1 files $config.TestResult.Enabled = $true $config.TestResult.OutputPath = GenXdev.FileSystem\Expand-Path ( ".\Tests\TestResults.xml" ) $config.Run.Path = GenXdev.FileSystem\Expand-Path ".\Tests\" # verify test files exist if (@(Microsoft.PowerShell.Management\Get-ChildItem .\Tests\*.Tests.ps1 -File -Recurse ` -ErrorAction SilentlyContinue).Count -eq 0) { Microsoft.PowerShell.Utility\Write-Warning "No tests found for module $($module.Name)" return } Microsoft.PowerShell.Utility\Write-Verbose "Running tests for module $($module.Name)" # execute module tests Pester\Invoke-Pester -Configuration $config | Microsoft.PowerShell.Core\ForEach-Object -ErrorAction SilentlyContinue { Microsoft.PowerShell.Utility\Write-Output $_ } } catch { throw $_.Exception.Message } } } } finally { # restore original location Microsoft.PowerShell.Utility\Write-Verbose "Restoring original location: $originalLocation" Microsoft.PowerShell.Management\Set-Location $originalLocation } } end { } ################################################################################ |