if you write regularly PowerShell modules, you have to test the functions in it.
i wrote some Pester tests, which are doing this tests for all functions in a PowerShell module:
- the function has SYNOPSIS, DESCRIPTION and EXAMPLES
- the function has cmdletbinding
- the function has an OutputType defined
- the function name starts with an approved verb
- the function name has an common prefix
- all parameters have a help text
- all parameters have a type declaration
- all variables inside the function has the same upper/lower case
#region declarations $TestsPath = Split-Path $MyInvocation.MyCommand.Path $ScriptName = Split-Path $MyInvocation.MyCommand.Definition -Leaf $FunctionName = @( $ScriptName -split '\.' )[0] Clear-Host $RootFolder = (get-item $TestsPath).Parent Push-Location -Path $RootFolder.FullName Set-Location -Path $RootFolder.FullName $ModulePath = Get-ChildItem -Filter "*.psm1" Import-Module $ModulePath.FullName -Force $Functions = Get-Command -Module $ModulePath.BaseName -CommandType Function $CommonPrefix = 'CommonPrefix' #endregion declarations #region Pester tests foreach ( $FunctionName in @( $Functions.Name | Sort-Object ) ) { Describe "default tests for $( $FunctionName )" { $command = Get-Command -Name $script:FunctionName -All $help = Get-Help -Name $script:FunctionName $Ast = $command.ScriptBlock.Ast <# @( $Ast.FindAll( { $true } , $true ) ) | Where-Object { $_.Extent.Text -eq '[cmdletbinding()]' } | select * @( $Ast.FindAll( { $true } , $true ) ) | Group-Object TypeName @( $Ast.FindAll( { $true } , $true ) ) | Out-Gridview #> $Verb = @( $script:FunctionName -split '-' )[0] It "verb '$( $Verb )' should be approved" { ( $Verb -in @( Get-Verb ).Verb ) | Should -Be $true } try { $FunctionPrefix = @( $script:FunctionName -split '-' )[1].Substring( 0, $CommonPrefix.Length ) } catch { $FunctionPrefix = @( $script:FunctionName -split '-' )[1] } it "function Noon should have the Prefix '$( $CommonPrefix )'" { $FunctionPrefix | Should -Be $CommonPrefix } It "Synopsis should exist" { ( $command.ScriptBlock -match '.SYNOPSIS' ) | Should -Be $true } It "Description should exist" { ( [string]::IsNullOrEmpty( $help.description.Text ) ) | Should -Be $false } It "Example should exist" { [boolean]( $help.examples ) | Should -Be $true } It "[CmdletBinding()] should exist" { [boolean]( @( $Ast.FindAll( { $true } , $true ) ) | Where-Object { $_.TypeName.Name -eq 'cmdletbinding' } ) | Should -Be $true } It "[OutputType] should exist" { [boolean]( @( $Ast.FindAll( { $true } , $true ) ) | Where-Object { $_.TypeName.Name -eq 'OutputType' } ) | Should -Be $true } Context "parameters" { $DefaultParams = @( 'Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable') foreach ( $p in @( $command.Parameters.Keys | Where-Object { $_ -notin $DefaultParams } | Sort-Object ) ) { It "help-text for paramater '$( $p )' should exist" { ( $p -in $help.parameters.parameter.name ) | Should -Be $true } $Declaration = ( ( @( $Ast.FindAll( { $true } , $true ) ) | Where-Object { $_.Name.Extent.Text -eq "$('$')$p" } ).Extent.Text -replace 'INT32', 'INT' ) $VariableType = ( "\[$( $command.Parameters."$p".ParameterType.Name )\]" -replace 'INT32', 'INT' ) $VariableTypeFull = "\[$( $command.Parameters."$p".ParameterType.FullName )\]" $VariableType = $command.Parameters."$p".ParameterType.Name -replace 'INT32', 'INT' It "type '[$( $command.Parameters."$p".ParameterType.Name )]' should be declared for parameter '$( $p )'" { ( ( $Declaration -match $VariableType ) -or ( $Declaration -match $VariableTypeFull ) ) | Should -Be $true } } } Context "variables" { $code = $command.ScriptBlock $ScriptVariables = $code.Ast.FindAll( { $true } , $true ) | Where-Object { $_.GetType().Name -eq 'VariableExpressionAst' } | Select-Object -Property VariablePath -ExpandProperty Extent foreach ( $sv in @( $ScriptVariables | Select-Object -ExpandProperty Text -Unique | Sort-Object ) ) { It "variable '$( $sv )' should be in same (upper/lower) case everywhere" { [boolean]( $ScriptVariables | Where-Object { ( ( $_.Text -eq $sv ) -and ( $_.Text -cne $sv ) ) } ) | Should -Be $false } } } } } #endregion Pester tests