PSSAToJunit.psm1
function ConvertTo-PSSAJunitXml { [CmdletBinding()] [OutputType([System.Xml.XmlDocument])] param ( [Parameter( Mandatory, ValueFromPipeline = $true )] [AllowNull()] [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]] $PSScriptAnalyzerResult, [Parameter()] [String] $TestName, [Parameter()] [ValidateSet("Information", "Warning", "Error")] [System.String[]] $Severity ) begin { try { if (!$TestName) { $TestName = "PSScriptAnalyzer" } if (!$Severity) { $Severity = @("Warning", "Error") } $TestSuites = Get-TestSuite -Severity $Severity } catch { Write-Error "Error occurred while initializing variables: $_" return } } process { try { if ($PSScriptAnalyzerResult) { foreach ($Result in $PSScriptAnalyzerResult) { if ($Result.RuleName -in $TestSuites.Keys) { $TestSuites[$Result.RuleName].FailedTests += @{ ScriptName = $Result.ScriptName Message = $Result.Message Line = $Result.Line ScriptPath = $Result.ScriptPath } } } } } catch { Write-Error "Error occurred while processing results: $_" return } } end { try { [System.Xml.XmlDocument]$JunitXml = ConvertTo-JunitXml -TestSuites $TestSuites -TestName $TestName Return $JunitXml } catch { Write-Error "Error occurred while converting to JUnit XML: $_" return } } } function Export-PSSAJunitXml { [CmdletBinding()] [OutputType([System.Xml.XmlDocument])] param ( [Parameter(Mandatory, ValueFromPipeline = $true)] [System.Xml.XmlDocument] $InputXml, [Parameter()] [System.IO.FileInfo] $FilePath ) begin { if (!$FilePath) { $FilePath = Join-Path -Path $PWD -ChildPath "PSScriptAnalyzerResults.xml" } } process { try { $InputXml.Save($FilePath) } catch { Write-Error "Error saving file: $_" } } end { if (Test-Path $FilePath) { Write-Debug "File created at: $FilePath" } else { Write-Error "File not created" } } } function ConvertTo-JunitXml { [CmdletBinding()] [OutputType([System.Xml.XmlDocument])] param ( [Parameter(Mandatory)] [System.Collections.Hashtable] $TestSuites, [Parameter(Mandatory)] [String] $TestName ) try { [System.Xml.XmlDocument]$JunitXml = Get-ParentXml -TestRunName $TestName foreach ($TestSuite in $TestSuites.GetEnumerator()) { [System.Xml.XmlDocument]$TestSuiteXml = Get-TestSuiteXml -TestSuiteName $TestSuite.Name foreach ($FailedTest in $TestSuite.Value.FailedTests) { [Hashtable]$GetTestCaseXmlArgs = @{ TestCaseName = $FailedTest.ScriptName TestCaseMessage = $FailedTest.Message TestCasePath = $FailedTest.ScriptPath Line = $FailedTest.Line } [System.Xml.XmlDocument]$TestCaseXml = Get-TestCaseXml @GetTestCaseXmlArgs $TestCaseRoot = $TestCaseXml.DocumentElement $ImportedNode = $TestSuiteXml.ImportNode($TestCaseRoot, $true) $TestSuiteXml.DocumentElement.AppendChild($ImportedNode) | Out-Null $TestSuiteXml.testsuite.tests = [int]($TestSuiteXml.testsuite.tests) + 1 $TestSuiteXml.testsuite.failures = [int]($TestSuiteXml.testsuite.failures) + 1 } if (![int]$TestSuiteXml.testsuite.failures) { $TestSuiteXml.testsuite.tests = 1 $TestSuiteXml.testsuite.failures = 0 } $TestSuiteRoot = $TestSuiteXml.DocumentElement $ImportedNode = $JunitXml.ImportNode($TestSuiteRoot, $true) $JunitXml.DocumentElement.AppendChild($ImportedNode) | Out-Null $JunitXml.testsuites.tests = [int]$JunitXml.testsuites.tests + [int]($TestSuiteXml.testsuite.tests) $JunitXml.testsuites.failures = [int]($JunitXml.testsuites.failures) + [int]($TestSuiteXml.testsuite.failures) } Return $JunitXml } catch { Write-Error "An error occurred while converting to JUnit XML: $_" } } function Get-ParentXml { [CmdletBinding()] [OutputType([System.Xml.XmlDocument])] param ( [Parameter(Mandatory)] [String] $TestRunName ) return [System.Xml.XmlDocument]@" <?xml version="1.0" encoding="utf-8" standalone="no"?> <testsuites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="junit_schema_4.xsd" name="$TestRunName" tests="0" errors="0" failures="0" disabled="0" time="0"> </testsuites> "@ } function Get-TestCaseXml { [CmdletBinding()] [OutputType([System.Xml.XmlDocument])] param ( [Parameter()] [String] $TestCaseName, [Parameter()] [String] $Severity, [Parameter()] [String] $TestCaseMessage, [Parameter()] [String] $TestCasePath, [Parameter()] [Int] $Line ) return [System.Xml.XmlDocument]@" <testcase id="" name="$TestCaseName" time="0.001"> <failure message="$TestCasePath"> $($Severity.ToUpper()): $TestCaseMessage File: $TestCasePath Line: $Line </failure> </testcase> "@ } function Get-TestSuite { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter()] [ValidateSet("Information", "Warning", "Error")] [System.String[]] $Severity ) try { $ScriptAnalyzerRules = Get-ScriptAnalyzerRule -Severity $Severity } catch { Write-Error "Failed to retrieve ScriptAnalyzer rules: $_" return } $TestSuites = @{} foreach ($Rule in $ScriptAnalyzerRules) { $TestSuites[$Rule.RuleName] = @{ Name = $Rule.RuleName Severity = $Rule.Severity Description = $Rule.Description FailedTests = @() } } return $TestSuites } function Get-TestSuiteXml { [CmdletBinding()] [OutputType([System.Xml.XmlDocument])] param ( [Parameter(Mandatory)] [String] $TestSuiteName ) return [System.Xml.XmlDocument]@" <testsuite name="$TestSuiteName" tests="0" errors="0" failures="0" hostname="" id="0" skipped="0" disabled="0" package="" time="0"> </testsuite> "@ } |