Get-CommandCoverage.ps1
function Get-CommandCoverage { <# .Synopsis Gets Command Coverage .Description Gets code coverage of the commands within a module. .Example Get-CommandCoverage .Link Test-Module .Link Enable-CommandCoverage .Link Disable-CommandCoverage #> [OutputType([PSObject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "", Justification="This needs to be global")] param( # The name of the module that will be instrumented for command coverage [Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)] [Alias('Name')] [string] $Module ) process { #region Caculate Command Coverage # First, get all functions from the module. $moduleCommands = Get-Command -Module $module -commandType Function # Then, find the commands that were hit. $commandsCovered = @($moduleCommands | Where-Object { $global:CommandCoverage.Contains("$_") } ) # Get the commands # Then, find the commands that were not hit. $missingCommands = @($moduleCommands | Where-Object { -not $global:CommandCoverage.Contains("$_") } ) $percentageCommandsCovered = # calculate the % command coverage. $commandsCovered.Count / $moduleCommands.Count #endregion Caculate Command Coverage #region Caculate Parameter Coverage $totalParameterCount = # Next, total up the number of parameters $moduleCommands | ForEach-Object { ([Management.Automation.CommandMetaData]$_).Parameters.Count} | Measure-Object -Sum | Select-Object -ExpandProperty Sum $coveredParameterTotal = $commandsCovered | ForEach-Object { ([Management.Automation.CommandMetaData]$_).Parameters.Count} | Measure-Object -Sum | Select-Object -ExpandProperty Sum $totalMissedParameters = 0 $totalCoveredParameters = 0 $specificCommandCoverage = $commandsCovered | # Next, walk thru each command ForEach-Object { $params = ([Management.Automation.CommandMetaData]$_).Parameters $coverageData = @($global:CommandCoverage["$_"]) # find coverage data related to that command # and see what parameters were missed. $missedParameters = @($params.Keys | Where-Object { -not ($coverageData -eq $_) }) $totalMissedParameters += $missedParameters.Count $coveredParams = @($coverageData | Group-Object -NoElement | Select-Object Name, @{ Expression={$_.Count} Name='TimesHit' }) # Then summarize how often each parameter was used. $totalCoveredParameters += $coveredParams.Count # Pack all of this information into a property bag for the command. $o = New-Object PSOBject -Property @{ Command = $_ CoveredParameters = $coveredParams MissedParameters = $missedParameters PercentageParameterCoverage = try { $coveredParams.Count * 100 / ($coveredParams.Count + $missedParameters.Count ) } catch { 1 } } # and decorate it as a 'ScriptCop.Command.Coverage' $o.pstypenames.clear() $o.pstypenames.add('ScriptCop.Command.Coverage') $o } #endregion Caculate Parameter Coverage $commandCoverageOutput = New-Object PSObject -Property @{ CommandsCovered = $commandsCovered CoveredParameterTotal = $coveredParameterTotal CoverageData = $specificCommandCoverage PercentageCommandCoverage = $percentageCommandsCovered * 100 NumberOfCommandsCovered = $commandsCovered.Count TotalNumberOfCommands = $moduleCommands.Count NumberOfParametersCovered = $totalCoveredParameters OverallParameterCoverage = $totalCoveredParameters * 100 / $totalParameterCount ParameterCoverageInCoveredCommands = $totalCoveredParameters * 100 / $coveredParameterTotal MissingCommands = $missingCommands TotalNumberOfParameters = $totalParameterCount } $commandCoverageOutput.pstypenames.clear() $commandCoverageOutput.pstypenames.add('ScriptCop.Command.Coverage.Report') $commandCoverageOutput } } |