当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 将 Pester 结果导入 PowerShell

作者:精品下载站 日期:2024-12-14 07:58:02 浏览:14 分类:玩电脑

将 Pester 结果导入 PowerShell


上周,Iron Scripter 网站上发布了 PowerShell 脚本挑战赛。这个想法是,当您运行 Pester 测试时,您可以将结果保存到特殊格式的 XML 文件中。

Invoke-Pester C:\scripts\sample.test.ps1 -OutputFile d:\temp\results.xml -OutputFormat JUnitXml

我得到这个结果。

[玩转系统] 将 Pester 结果导入 PowerShell

[玩转系统] 将 Pester 结果导入 PowerShell

剧透警报

我编写了使用 JunitXML 格式重新创建 Pester 结果的函数。在某些时候修改该函数以能够处理两种 XML 格式会很好。我写的函数有一个 Path 参数。我可以指定一个值或通过管道将文件传递给命令。

Param(
        [Parameter(position = 0, ValueFromPipeline, HelpMessage = "Specify the path to the JunitXML Pester test file.")]
        [ValidateNotNullorEmpty()]
        #verify the file exists and it is an XML file
        [ValidateScript({
            If ((Test-Path $_) -AND ($_.split('.')[-1] -eq 'XML' )) {
                $True
            }
            else {
                #display a custom validation error message
                Throw "The file could not be found or wasn't an XML file."
            }
        })]
        [Alias("pspath")]
        [string]$Path
    )

参数定义使用了一些验证测试。主要测试是确保文件存在并且以 XML 结尾。稍后我还有其他验证来测试它是否是 JunitXML 文件。是的,我知道从技术上讲我可以使用任何文件扩展名导出结果,但我假设 XML 加上我想演示这种技术。

参数中的另一个功能是我正在创建自己的自定义错误消息。当您使用 [ValidateScript()] 时,脚本块必须为您提供 True 或 False。就我而言,如果测试失败,我将抛出自定义错误消息。

[玩转系统] 将 Pester 结果导入 PowerShell

PowerShell 7 可以更好地处理这个问题。

[玩转系统] 将 Pester 结果导入 PowerShell

此时就需要解析 XML 文档了。

Process {
        Write-Verbose "Processing $Path"
        [xml]$doc = Get-Content -path $Path

我可以查看 XML 内部以确定这是否是一个 junit 文件。如果不是,我就会退出命令。

if ($doc.testsuites.noNamespaceSchemaLocation -notmatch "junit") {
            Write-Warning "Could not import $Path. You must specify a Pester test result file using the JUnitXML format."
            #abort
            return
        }

否则,我将解析文档以获取元数据信息,该信息组装在此处字符串中并使用 Write-Host 写入主机。事实上,整个函数使用 Write-Host 直接写入控制台。没有任何内容写入管道。尽管我稍后会向您展示一个选项。对于这个挑战,使用 Write-Host 是完全可以的。另一种选择是为 PowerShell 7 编写函数版本并使用 ANSI 转义进行着色。我会留到下次再写,或者你也可以写下来。

解析测试

棘手的部分是解析测试结果。我有这个 XML 可以使用。

<testcase name="Alpha.Should have a value over 1" status="Passed" classname="C:\work\sample.test.ps1" assertions="0" time="0.465" />
    <testcase name="Alpha.Should fail on a null value" status="Failed" classname="C:\work\sample.test.ps1" assertions="0" time="0.190">
      <failure message="Expected $true, but got $false." />
    </testcase>
    <testcase name="Alpha.Should accept a mandatory Computername parameter" status="Passed" classname="C:\work\sample.test.ps1" assertions="0" time="0.300" />
    <testcase name="Alpha.Testing.Should have a value of 4" status="Passed" classname="C:\work\sample.test.ps1" assertions="0" time="0.894" />
    <testcase name="Alpha.Testing.Should run without error" status="Passed" classname="C:\work\sample.test.ps1" assertions="0" time="1.150" />
    <testcase name="Bravo.Should have a value less than 1" status="Passed" classname="C:\work\sample.test.ps1" assertions="0" time="0.525" />
    <testcase name="Bravo.Should export the gravitational constant" status="Skipped" classname="C:\work\sample.test.ps1" assertions="0" time="0.000">
      <skipped message="" />
    </testcase>
    <testcase name="Bravo.Should run without errors" status="Passed" classname="C:\work\sample.test.ps1" assertions="0" time="2.357" />
    <testcase name="Bravo.Should run with credentials" status="Pending" classname="C:\work\sample.test.ps1" assertions="0" time="0.000">
      <skipped message="" />
    </testcase>

Name 属性是关键项。第一部分,直到第一期,是描述块。在我的示例中,这是 Alpha 和 Bravo。句号之后的任何内容都是断言或 It 语句。除非,有一个像“测试”这样的中间词。这是一个 Pester 上下文元素。

我尝试了几种技巧来分解这段文字。最终我决定使用正则表达式模式。

[regex]$rx = "(?^[\w-_\s]+(?=\.))\.((?(?<=\.)\w+(?=\.))\.)?(?(?<=\.).*)"

该模式使用命名捕获来识别描述、上下文和断言组件。

想要了解有关 PowerShell 中正则表达式的更多信息?我为 Pluralsight 创建了一个关于该主题的完整课程。

我使用此模式将每个测试用例转换为自定义对象。

$tests = $doc.testsuites.testsuite.testcase | Group-Object -property Name
        Write-Verbose "Processing $($tests.count) tests"

        #turn each test into an object using a regex to split
        $testobj = foreach ($test in $Tests) {
            $m = $rx.Matches($test.name)
            [pscustomobject]@{
                Describe  = $m.groups[2]
                Context   = $m.groups[3]
                Assertion = $m.groups[4]
                TestCase  = $test.group
            }
        } #foreach test

我发现这更容易使用。现在我可以使用 Group-Object 和 ForEach 等命令以有序的方式处理结果,将结果写入基于主机的 east 测试。我最终创建了一个私有辅助函数 _parseTestCase,它将结果写入主机。当您查看代码时,您会发现我正在使用 Switch 语句来确定要使用的符号和前景色。

作为摘要,我将 Status 属性上的 TestCase 节点分组为哈希表。哈希表的键将是“失败”和“跳过”之类的内容。这使得我可以轻松获得需要显示的计数。

#write the summary information to the host in color
        $testHash = $doc.testsuites.testsuite.testcase | Group-Object -property Status -AsHashTable -AsString

        Write-Host "Tests completed in $(New-TimeSpan -seconds $doc.testsuites.time)" -ForegroundColor White
        Write-Host "Tests Passed: $($doc.testsuites.tests), " -ForegroundColor White -NoNewline
        Write-Host "Failed: $($TestHash["Failed"].count), " -ForegroundColor Red -NoNewline
        Write-Host "Skipped: $($TestHash["Skipped"].count), " -ForegroundColor Yellow -NoNewline
        Write-Host "Pending: $($TestHash["Pending"].count), " -ForegroundColor gray -NoNewline
        Write-Host "Inconclusive: $($TestHash["Inconclusive"].count)" -ForegroundColor DarkGray

Import-TestResultFile.ps1:

#requires -version 5.1

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯