Functions/TestResults.ps1
function Get-HumanTime($Seconds) { if($Seconds -gt 0.99) { $time = [math]::Round($Seconds, 2) $unit = "s" } else { $time = [math]::Floor($Seconds * 1000) $unit = "ms" } return "$time$unit" } function GetFullPath ([string]$Path) { $fullpath = Resolve-Path -Path $Path -ErrorAction SilentlyContinue -ErrorVariable Error if ($fullpath) { $fullpath } else { $error[0].TargetObject } } function Export-NUnitReport { param ( [parameter(Mandatory=$true,ValueFromPipeline=$true)] [PSObject]$InputObject, [parameter(Mandatory=$true)] [String]$Path ) #the xmlwriter create method can resolve relatives paths by itself. but its current directory might #be different from what PowerShell sees as the current directory so I have to resolve the path beforehand #working around the limitations of Resolve-Path $Path = GetFullPath -Path $Path # Create The Document $settings = New-Object -TypeName Xml.XmlWriterSettings $settings.Indent = $true $settings.NewLineOnAttributes = $false try { $XmlWriter = [Xml.XmlWriter]::Create($Path,$settings) # Write the XML Declaration $XmlWriter.WriteStartDocument($false) # Write Root Element $xmlWriter.WriteStartElement("test-results") $XmlWriter.WriteAttributeString("xmlns","xsi", $null, "http://www.w3.org/2001/XMLSchema-instance") $XmlWriter.WriteAttributeString("xsi","noNamespaceSchemaLocation", [Xml.Schema.XmlSchema]::InstanceNamespace , "nunit_schema_2.5.xsd") $XmlWriter.WriteAttributeString("name","Pester") $XmlWriter.WriteAttributeString("total", $InputObject.TotalCount) $XmlWriter.WriteAttributeString("errors", "0") $XmlWriter.WriteAttributeString("failures", $InputObject.FailedCount) $XmlWriter.WriteAttributeString("not-run", "0") $XmlWriter.WriteAttributeString("inconclusive", "0") $XmlWriter.WriteAttributeString("ignored", "0") $XmlWriter.WriteAttributeString("skipped", "0") $XmlWriter.WriteAttributeString("invalid", "0") $date = Get-Date $XmlWriter.WriteAttributeString("date", (Get-Date -Date $date -Format "yyyy-MM-dd")) $XmlWriter.WriteAttributeString("time", (Get-Date -Date $date -Format "HH:mm:ss")) #Write environment information $XmlWriter.WriteStartElement("environment") $environment = Get-RunTimeEnvironment $environment.GetEnumerator() | foreach { $XmlWriter.WriteAttributeString($_.Name, $_.Value) } $XmlWriter.WriteEndElement() #Close the Environment tag #Write culture information $XmlWriter.WriteStartElement("culture-info") $XmlWriter.WriteAttributeString("current-culture", ([System.Threading.Thread]::CurrentThread.CurrentCulture).Name) $XmlWriter.WriteAttributeString("current-uiculture", ([System.Threading.Thread]::CurrentThread.CurrentUiCulture).Name) $XmlWriter.WriteEndElement() #Close culture-info tag #Write root test-suite element containing all the describes $XmlWriter.WriteStartElement("test-suite") $XmlWriter.WriteAttributeString("type", "Powershell") $XmlWriter.WriteAttributeString("name", $InputObject.Path) $XmlWriter.WriteAttributeString("executed", "True") $isSuccess = $inputObject.FailedCount -eq 0 $result = if ($isSuccess) { "Success" } else { "Failure"} $XmlWriter.WriteAttributeString("result", $result) $XmlWriter.WriteAttributeString("success",[string]$isSuccess) $XmlWriter.WriteAttributeString("time",(Convert-TimeSpan $InputObject.Time)) $XmlWriter.WriteAttributeString("asserts","0") $XmlWriter.WriteStartElement("results") $Describes = $InputObject.TestResult | Group -Property Describe $Describes | foreach { $currentDescribe = $_ $DescribeInfo = Get-TestSuiteInfo $currentDescribe #Write test suites $XmlWriter.WriteStartElement("test-suite") $XmlWriter.WriteAttributeString("type", "Powershell") $XmlWriter.WriteAttributeString("name", $DescribeInfo.name) $XmlWriter.WriteAttributeString("executed", "True") $XmlWriter.WriteAttributeString("result", $DescribeInfo.resultMessage) $XmlWriter.WriteAttributeString("success", $DescribeInfo.success) $XmlWriter.WriteAttributeString("time",$DescribeInfo.totalTime) $XmlWriter.WriteAttributeString("asserts","0") $XmlWriter.WriteStartElement("results") #Write test-results $currentDescribe.Group | foreach { $XmlWriter.WriteStartElement("test-case") $XmlWriter.WriteAttributeString("name", $_.Name) $XmlWriter.WriteAttributeString("executed", "True") $XmlWriter.WriteAttributeString("time", (Convert-TimeSpan $_.Time)) $XmlWriter.WriteAttributeString("asserts", "0") $XmlWriter.WriteAttributeString("success", $_.Passed) if ($_.Passed) { $XmlWriter.WriteAttributeString("result", "Success") } else { $XmlWriter.WriteAttributeString("result", "Failure") $XmlWriter.WriteStartElement("failure") $xmlWriter.WriteElementString("message", $_.FailureMessage) $XmlWriter.WriteElementString("stack-trace", $_.StackTrace) $XmlWriter.WriteEndElement() # Close failure tag } $XmlWriter.WriteEndElement() #Close test-case tag } $XmlWriter.WriteEndElement() #Close results tag $XmlWriter.WriteEndElement() #Close test-suite tag } $XmlWriter.WriteEndElement() #Close results tag $XmlWriter.WriteEndElement() #Close test-suite tag $XmlWriter.WriteEndElement() #Close the test-result tag $XmlWriter.Flush() } finally { if ($XmlWriter) { #make sure the writer is closed, otherwise it keeps the file locked try { $xmlWriter.Close() } catch {} } } } function Get-TestSuiteInfo ($DescribeGroup) { $suite = @{ resultMessage = "Failure" success = "False" totalTime = "0.0" name = $DescribeGroup.name } #calculate the time first, I am converting the time into string in the TestCases $suite.totalTime = (Get-TestTime $DescribeGroup.Group) $suite.success = (Get-TestSuccess $DescribeGroup.Group) if($suite.success -eq "True") { $suite.resultMessage = "Success" } $suite } function Convert-TimeSpan { param ( [Parameter(ValueFromPipeline=$true)] $TimeSpan ) process { if ($TimeSpan) { [string][math]::round(([TimeSpan]$TimeSpan).totalseconds,4) } else { "0" } } } function Get-TestTime($tests) { [TimeSpan]$totalTime = 0; if ($tests) { $tests | foreach { $totalTime += $_.time } } $totalTime | Convert-TimeSpan } function Get-TestSuccess($tests) { #if any fails, the whole suite fails $result = $true $tests | foreach { if (-not $_.Passed) { $result = $false } } [String]$result } function Get-RunTimeEnvironment() { $osSystemInformation = (Get-WmiObject Win32_OperatingSystem) @{ "nunit-version" = "2.5.8.0" "os-version" = $osSystemInformation.Version platform = $osSystemInformation.Name cwd = (Get-Location).Path #run path "machine-name" = $env:ComputerName user = $env:Username "user-domain" = $env:userDomain "clr-version" = $PSVersionTable.ClrVersion.ToString() } } function Exit-WithCode ($FailedCount) { $host.SetShouldExit($FailedCount) } |