Created
June 12, 2017 19:43
-
-
Save iainbrighton/49b2e4ccac47f9315944c2d9ec8e5026 to your computer and use it in GitHub Desktop.
Sample colourised Format-Pester output
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function Format-Pester { | |
<# | |
.SYNOPSIS | |
Document Pester's tests results into the selected format (HTML, Word, Text). | |
.DESCRIPTION | |
Create documents in formats: HTML, Word, Text using PScribo PowerShell module. Documents are preformated to be human friendly. | |
Local Word installation is not needed to be installed on the computers were documents. | |
Additional languages (other than en-US) can be used - please read info for translator on the project web page. | |
.PARAMETER PesterResult | |
Specifies the Pester results Object | |
.PARAMETER Format | |
Specifies the document format. Might be: | |
- Text | |
- HTML | |
- Word | |
.PARAMETER Path | |
Specifies where the documents will be stored. Default is the path where is executed this function. | |
.PARAMETER BaseFileName | |
Specifies the document name. Default is 'Pester_Results'. | |
.PARAMETER Order | |
Specify what results need to be evaluated first - passed or failed - means that will be included on the top of report. | |
By default failed tests are evaluated first. | |
.PARAMETER GroupResultsBy | |
Select how results should be groupped. Available options: Result, Result-Describe, Result-Describe-Context. | |
.PARAMETER PassedOnly | |
Select to return information about passed tests only. | |
.PARAMETER FailedOnly | |
Select to return information about failed tests only. | |
.PARAMETER SummaryOnly | |
Select to return only summaries for tests only (sums of numbers passed/failed/etc. tests). | |
.PARAMETER SkipTableOfContent | |
Select to skip adding table of content at the begining of document(s). | |
.PARAMETER SkipSummary | |
Select to skip adding table with test summaries (sums of numbers passed/failed/etc. tests). | |
.PARAMETER Language | |
Select language what need to be used for generated reports. | |
By default language is detected by Get-Culture with fallback to en-US if translation is not available. | |
.PARAMETER Version | |
Use that parameter to display version of Format-Pester only. | |
This parameter can be used to verify translations. | |
.PARAMETER DumpPScriboObject | |
When DumpPscriboObject is used the result of the function is custom object containing PScribo Document. | |
Use this parameter for prepare tests or debug of document generation. | |
.INPUTS | |
An expected input is the result of the command Invoke-Pester with the parameter -PassThru. | |
With that command Invoke-Pester returns a custom object (PSCustomObject) that contains the test results. | |
.OUTPUTS | |
Files what contain results of test. Files format and structure is based on values of parameters used. | |
.EXAMPLE | |
Invoke-Pester -PassThru | Format-Pester -Path . -Format HTML,Word,Text -BaseFileName 'PesterResults' | |
This command will document the results of the Pester's tests. | |
Documents will be stored in the current path and they will be available in 3 formats (.html,.docx and .txt). | |
.EXAMPLE | |
Invoke-Pester -PassThru | Export-Clixml -Path .\Test-Result.xml | |
Import-Clixml -Path .\Test-Result.xml | Format-Pester -Format .\ -BaseFileName Test-Result -Format HTML -FailedOnly | |
The first command you can run e.g. on a server where PScribo and Format-Pester is not installed. The tests results will be stored in a file as xml representation of object. | |
After copy the file to the computer where PScribo and Format-Pester are available you can generate report. The html file will be generated with results of failed tests only. | |
.LINK | |
https://github.com/equelin/Format-Pester | |
.LINK | |
https://github.com/iainbrighton/PScribo | |
.NOTES | |
Initial author: Erwan Quelin | |
Credits/coauthors: | |
- Travis Plunk, github[at]ez13[dot]net | |
- Wojciech Sciesinski, wojciech[at]sciesinski[dot]net | |
LICENSE | |
Licensed under the MIT License - https://github.com/equelin/Format-Pester/blob/master/LICENSE | |
#> | |
[CmdletBinding(DefaultParameterSetName = 'AllParamSet')] | |
[OutputType([IO.FileInfo])] | |
Param ( | |
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True, ValueFromPipelinebyPropertyName = $True, HelpMessage = 'Pester results Object', ParameterSetName = 'AllParamSet')] | |
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True, ValueFromPipelinebyPropertyName = $True, HelpMessage = 'Pester results Object', ParameterSetName = 'PassedOnlyParamSet')] | |
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True, ValueFromPipelinebyPropertyName = $True, HelpMessage = 'Pester results Object', ParameterSetName = 'FailedOnlyParamSet')] | |
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True, ValueFromPipelinebyPropertyName = $True, HelpMessage = 'Pester results Object', ParameterSetName = 'SummaryOnlyParamSet')] | |
[Parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $True, ValueFromPipelinebyPropertyName = $True, HelpMessage = 'Pester results Object', ParameterSetName = 'VersionOnlyParamSet')] | |
[Array]$PesterResult, | |
[Parameter(Mandatory = $true, HelpMessage = 'PScribo export format', ParameterSetName = 'AllParamSet')] | |
[Parameter(Mandatory = $true, ParameterSetName = 'PassedOnlyParamSet')] | |
[Parameter(Mandatory = $true, ParameterSetName = 'FailedOnlyParamSet')] | |
[Parameter(Mandatory = $true, ParameterSetName = 'SummaryOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'VersionOnlyParamSet')] | |
[ValidateSet('Text', 'Word', 'HTML')] | |
[String[]]$Format, | |
[Parameter(Mandatory = $false, HelpMessage = 'PScribo export path', ParameterSetName = 'AllParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'PassedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'FailedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'SummaryOnlyParamSet')] | |
[ValidateNotNullorEmpty()] | |
[String]$Path = (Get-Location -PSProvider FileSystem), | |
[ValidateNotNullorEmpty()] | |
[string]$BaseFileName = 'Pester_Results', | |
[Parameter(Mandatory = $false, ParameterSetName = 'AllParamSet')] | |
[ValidateSet('FailedFirst', 'PassedFirst')] | |
[String]$Order = 'FailedFirst', | |
[Parameter(Mandatory = $false, ParameterSetName = 'AllParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'PassedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'FailedOnlyParamSet')] | |
[ValidateSet('Result', 'Result-Describe', 'Result-Describe-Context')] | |
[String]$GroupResultsBy = 'Result', | |
[Parameter(Mandatory = $false, ParameterSetName = 'PassedOnlyParamSet')] | |
[Switch]$PassedOnly, | |
[Parameter(Mandatory = $false, ParameterSetName = 'FailedOnlyParamSet')] | |
[Switch]$FailedOnly, | |
[Parameter(Mandatory = $false, ParameterSetName = 'SummaryOnlyParamSet')] | |
[switch]$SummaryOnly, | |
[Parameter(Mandatory = $false, ParameterSetName = 'AllParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'PassedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'FailedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'SummaryOnlyParamSet')] | |
[Switch]$SkipTableOfContent, | |
[Parameter(Mandatory = $false, ParameterSetName = 'AllParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'PassedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'FailedOnlyParamSet')] | |
[Switch]$SkipSummary, | |
[Parameter(Mandatory = $false, ParameterSetName = 'AllParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'PassedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'FailedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'SummaryOnlyParamSet')] | |
[String]$Language = $($(Get-Culture).Name), | |
[Parameter(Mandatory = $false, ParameterSetName = 'VersionOnlyParamSet')] | |
[Switch]$Version, | |
[Parameter(Mandatory = $false, ParameterSetName = 'AllParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'PassedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'FailedOnlyParamSet')] | |
[Parameter(Mandatory = $false, ParameterSetName = 'SummaryOnlyParamSet')] | |
[Switch]$DumpPScriboObject | |
) | |
[Version]$ScriptVersion = "1.4.2" | |
If ($Version.IsPresent) { | |
Return $ScriptVersion.ToString() | |
Break | |
} | |
Else { | |
if ($null -eq $PesterResult) { | |
$MessageText = "Value of the parameter PesterResult can't be null or empty." | |
Throw $MessageText | |
} | |
} | |
Import-LocalizedData -FileName Format-Pester.psd1 -BindingVariable LocalizedStrings -UICulture $Language -ErrorAction SilentlyContinue | |
If ([String]::IsNullOrEmpty($LocalizedStrings)) { | |
Import-LocalizedData -FileName Format-Pester.psd1 -BindingVariable LocalizedStrings -UICulture 'en-US' -ErrorAction Stop | |
[String]$MessageText = "{0} {1} {2}" -f $LocalizedStrings.msg27, $Language, $LocalizedStrings.msg28 | |
Write-Verbose -Message $MessageText | |
} | |
If ($LocalizedStrings.msg00 -lt $ScriptVersion) { | |
[String]$MessageText = "{0}" -f $LocalizedStrings.msg29 | |
Write-Warning -Message $MessageText | |
} | |
$TextFileEncoding = $LocalizedStrings.msg32 | |
#LocalizedStrings are not sorted alphabeticaly -even if you are using Sort-Object ! | |
#$LocalizedStrings | |
## Plugins should ignore options not meant for them | |
$exportParams = @{ | |
Options = @{ | |
Encoding = $TextFileEncoding | |
NoPageLayoutStyle = $true | |
} | |
} | |
$PScriboObject = Document $BaseFileName { | |
# Global options | |
# Set margins to 1.25cm (or 1/2 inch) and enable section numbering | |
GlobalOption -PageSize A4 -Margin 36 -EnableSectionNumbering | |
If (-not $SkipTableOfContent.ispresent) { | |
# Table of content header text | |
[String]$TOCName = $LocalizedStrings.msg01 | |
TOC -Name $TOCName | |
} | |
If (-not $SkipSummary.IsPresent) { | |
# Columns used for the summary table | |
#This variable can't be translated | |
$SummaryColumnsData = @('TotalCount', 'PassedCount', 'FailedCount', 'SkippedCount', 'PendingCount') | |
$SummaryColumnsHeaders = @($LocalizedStrings.msg02, $LocalizedStrings.msg03, $LocalizedStrings.msg04, $LocalizedStrings.msg05, $LocalizedStrings.msg06) | |
## Override the built in style(s) | |
Style -Name TOC -Size 16 -Color 3b3838 -Hide | |
Style -Name 'Heading 1' -Size 16 -Color 3b3838 | |
Style -Name 'Heading 2' -Size 14 -Color 3b3838 | |
Style -Name 'Heading 3' -Size 12 -Color 3b3838 | |
Style -Name TableDefaultHeading -Size 11 -Color fff -Bold -BackgroundColor 767171 | |
Style -Name TableDefaultRow -Size 11 | |
Style -Name TableDefaultAltRow -BackgroundColor ededed | |
TableStyle TableDefault -BorderWidth 1 -BorderColor a5a5a5 -HeaderStyle TableDefaultHeading -RowStyle TableDefaultRow -AlternateRowStyle TableDefaultAltRow -Default | |
Style -Name TablePassedHeading -Size 11 -Color fff -Bold -BackgroundColor 70ad47 | |
Style -Name TablePassedRow -Size 11 | |
Style -Name TablePassedAltRow -BackgroundColor e2efd9 | |
TableStyle TablePassed -BorderWidth 1 -BorderColor 70ad47 -HeaderStyle TablePassedHeading -RowStyle TablePassedRow -AlternateRowStyle TablePassedAltRow | |
Style -Name TableFailedHeading -Size 11 -Color fff -Bold -BackgroundColor 9c0006 | |
Style -Name TableFailedRow -Size 11 | |
Style -Name TableFailedAltRow -BackgroundColor ffc7ce | |
TableStyle TableFailed -BorderWidth 1 -BorderColor 9c0006 -HeaderStyle TableFailedHeading -RowStyle TableFailedRow -AlternateRowStyle TableFailedAltRow | |
# Style definitions used for the summary table | |
Style -Name TableSummaryHeading -Size 14 -Color fff -BackgroundColor a5a5a5 -Align Center | |
Style -Name TableSummaryRow -Size 24 | |
Style -Name TableSummaryAltRow -BackgroundColor ededed | |
TableStyle -Id SummaryTable -BorderWidth 1 -BorderColor a5a5a5 -HeaderStyle TableSummaryHeading -RowStyle TableSummaryRow | |
Style -Name Total -Color 2a70be -Size 24 -Bold -Align Center | |
Style -Name Passed -Color 006100 -BackgroundColor c6efce -Size 24 -Bold -Align Center | |
Style -Name Failed -Color 9c0006 -Size 24 -BackgroundColor ffc7ce -Bold -Align Center | |
Style -Name Other -Color 767171 -Size 24 -BackgroundColor dbdbdb -Bold -Align Center | |
$ValidResults = $PesterResult | Where-Object { $null -ne $_.TotalCount } | Sort-Object -Property FailedCount -Descending | |
Section -Name $LocalizedStrings.msg07 -Style Heading1 -ScriptBlock { | |
$ValidResults | Set-Style -Style 'Total' -Property 'TotalCount' | |
$ValidResults | Set-Style -Style 'Passed' -Property 'PassedCount' | |
$ValidResults | Set-Style -Style 'Failed' -Property 'FailedCount' | |
$ValidResults | Set-Style -Style 'Other' -Property 'SkippedCount' | |
$ValidResults | Set-Style -Style 'Other' -Property 'PendingCount' | |
## Set table width to 100% of available space | |
$ValidResults | Table -Columns $SummaryColumnsData -Headers $SummaryColumnsHeaders -Style SummaryTable | |
} | |
} | |
If (-not $SummaryOnly.IsPresent) { | |
#Expanding Pester summary to receive all tests results | |
$PesterTestsResults = $PesterResult | Select-Object -ExpandProperty TestResult | |
[Array]$EvaluateResults = $null | |
If ((-not $PassedOnly.IsPresent) -and $PesterResult.FailedCount -gt 0) { | |
$EvaluateResults += 'Failed' | |
} | |
If ((-not $FailedOnly.IsPresent) -and $PesterResult.PassedCount -gt 0) { | |
$EvaluateResults += 'Passed' | |
If ($Order -eq 'PassedFirst') { | |
$EvaluateResults = $($EvaluateResults | Sort-Object -Descending) | |
} | |
} | |
foreach ($CurrentResultType in $EvaluateResults) { | |
switch ($CurrentResultType) { | |
'Passed' { | |
$CurrentResultTypeLocalized = $LocalizedStrings.msg09 | |
$Head1SectionTitle = $LocalizedStrings.msg25 | |
$Header1TitlePart = $LocalizedStrings.msg10 | |
$Header2TitlePart = $LocalizedStrings.msg11 | |
$Header3TitlePart = $LocalizedStrings.msg12 | |
$VerboseMsgHeader2Part = $LocalizedStrings.msg13 | |
$VerboseMsgHeader3Part = $LocalizedStrings.msg14 | |
#This variable can't be translated | |
$TestsResultsColumnsData = @('Describe', 'Context', 'Name') | |
$TestsResultsColumnsHeaders = @($LocalizedStrings.msg15, $LocalizedStrings.msg16, $LocalizedStrings.msg17) | |
$TableStyleName = 'TablePassed' | |
} | |
'Failed' { | |
$CurrentResultTypeLocalized = $LocalizedStrings.msg18 | |
$Head1SectionTitle = $LocalizedStrings.msg26 | |
$Header1TitlePart = $LocalizedStrings.msg19 | |
$Header2TitlePart = $LocalizedStrings.msg20 | |
$Header3TitlePart = $LocalizedStrings.msg21 | |
$VerboseMsgHeader2Part = $LocalizedStrings.msg22 | |
$VerboseMsgHeader3Part = $LocalizedStrings.msg23 | |
#This variable can't be translated | |
$TestsResultsColumnsData = @('Context', 'Name', 'FailureMessage') | |
$TestsResultsColumnsHeaders = @($LocalizedStrings.msg16, $LocalizedStrings.msg17, $LocalizedStrings.msg24) | |
$TableStyleName = 'TableFailed' | |
} | |
default { | |
$TableStyleName = 'TableDefault' | |
} | |
} | |
$VerboseMsgMainLoop = $LocalizedStrings.msg08 | |
[String]$MessageText = "{0} {1} " -f $VerboseMsgMainLoop, $CurrentResultTypeLocalized | |
Write-Verbose -Message $MessageText | |
If (-not $PassedOnly.IsPresent) { | |
$CurrentPesterTestResults = $PesterTestsResults | Where-object -FilterScript { $_.Result -eq $CurrentResultType } | |
If ($GroupResultsBy -eq 'Result') { | |
Section -Name $Header1TitlePart -Style Heading1 { | |
$CurrentPesterTestResults | | |
Table -Columns $TestsResultsColumnsData -Headers $TestsResultsColumnsHeaders -Style $TableStyleName | |
} | |
} | |
Else { | |
Section -Name $Head1SectionTitle -Style Heading1 -ScriptBlock { | |
#Get unique 'Describe' from Pester results | |
[Array]$Headers2 = $CurrentPesterTestResults | Select-Object -Property Describe -Unique | |
# Tests results details - Grouped by Describe | |
foreach ($Header2 in $Headers2) { | |
[String]$MessageText = "{0}: {1} " -f $VerboseMsgHeader2Part, $($Header2.Describe) | |
Write-Verbose -Message $MessageText | |
[String]$Header2Title = "{0} {1}" -f $Header2TitlePart, $($Header2.Describe) | |
Section -Name $Header2Title -Style Heading2 -ScriptBlock { | |
$CurrentPesterTestResults2 = $CurrentPesterTestResults | Where-Object -FilterScript { $_.Describe -eq $Header2.Describe } | |
If ($GroupResultsBy -eq 'Result-Describe-Context') { | |
[Array]$Headers3 = $CurrentPesterTestResults2 | Select-Object -Property Context -Unique | |
foreach ($Header3 in $Headers3) { | |
[String]$MessageText = "{0}: {1} " -f $VerboseMsgHeader3Part, $($Header3.Context) | |
Write-Verbose -Message $MessageText | |
$CurrentPesterTestResults3 = $CurrentPesterTestResults2 | Where-Object -FilterScript { $_.Context -eq $Header3.Context } | |
$CurrentPesterTestResultsCount3 = ($CurrentPesterTestResults3 | Measure-Object).Count | |
[String]$Header3Title = "{0} {1}" -f $Header3TitlePart, $($Header3.Context) | |
Section -Name $Header3Title -Style Heading3 -ScriptBlock { | |
$MessageText = "{0} {1} {2}, {3} {4}" -f $LocalizedStrings.msg30, $Header3TitlePart, $($Header3.Context), $LocalizedStrings.msg31, $CurrentPesterTestResultsCount3 | |
Write-Verbose -Message $MessageText | |
$CurrentPesterTestResults3 | | |
Table -Columns $TestsResultsColumnsData -Headers $TestsResultsColumnsHeaders -Style $TableStyleName | |
} | |
} | |
} #$GroupResultsBy -eq 'Result-Describe-Context' | |
Else { | |
$MessageText = "{0} {1} {2}, {3}: {4}" -f $LocalizedStrings.msg30, $Header3TitlePart, $($Header3.Context), $LocalizedStrings.msg31, $CurrentPesterTestResultsCount3 | |
Write-Verbose -Message $MessageText | |
$CurrentPesterTestResults2 | | |
Table -Columns $TestsResultsColumnsData -Headers $TestsResultsColumnsHeaders -Style $TableStyleName | |
} | |
} | |
} #end foreach ($Header2 in $Headers2) | |
} | |
} #end $GroupResultsBy -ne 'Result' | |
} | |
} | |
} | |
} | |
If ($DumpPScriboObject.IsPresent) { | |
Return $PScriboObject | |
} | |
## PScribo 0.7.15 now requires -PassThru to return file(s) to the pipeline | |
$PScriboObject | Export-Document -Path $Path -Format $Format @exportParams -PassThru | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment