简体   繁体   中英

Is there a better way for me to loop through json nodes in PowerShell

I am wondering if someone could help me and make a suggestion.

I have a JSON file as seen below that contains a few different nodes, I have removed the values for confidentiality purposes. I need to be able to loop through each test step as provided by the JSON and pull the tests that have a step with a status of failed.

So far the easiest way I have found of doing this is nesting for each loop's (Report-> Description-> Element-> Step-> Result-> Status) I am wondering if there are any PowerShell Gurus that can assist me in finding a possible cleaner and faster solution for this?

[
  {
    "description": "",
    "elements": [
      {
        "description": "",
        "id": "",
        "keyword": "Scenario",
        "line": 9,
        "name": "",
        "tags": [
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          }
        ],
        "steps": [
          {
            "keyword": "Given ",
            "line": 0,
            "match": {
              "location": ""
            },
            "name": "",
            "result": {
              "duration": 41560.8294,
              "error_message": null,
              "status": "Failed"
            }
          }
        ],
    "name": "",
    "uri": ""
  },
  {
    "description": "",
    "elements": [
      {
        "description": "",
        "id": "",
        "keyword": "Scenario",
        "line": 14,
        "name": "",
        "tags": [
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          },
          {
            "name": "",
            "line": 1
          }
        ],
        "steps": [
          {
            "keyword": "Given ",
            "line": 0,
            "match": {
              "location": ""
            },
            "name": "",
            "result": {
              "duration": 17133.4242,
              "error_message": ,
              "status": ""
            }
          }
        ],
    "name": "",
    "uri": ""
  }
]
[String]$report = Get-Content $inputPath
[System.Object[]]$json = ConvertFrom-Json -InputObject "$report"

[String[]]$failedTests = @()

foreach($feature in $json)
{
    foreach($scenario in $feature.elements)
    {
        foreach($step in $scenario.steps)
        {
            if(($scenario.steps).Where({ $step.result.status -eq "Failed" }, 'First').Count -gt 0)
            {
                $failedTests += Generate-FullyQualifiedName $ProjectName $feature.name $scenario.name
                break
            }
        }
    }            
}

What you've got is pretty much the best way to return multiple "depths" of an object in powershell, since there's not really a.

One improvement is to force powershell to use a [list[]] type object instead of the default fixed-length [System.Array] created by $foo = @() , which has to be destroyed and recreated every time it's extended with += . Instead, try using:

$failedTests = [System.Collections.Generic.List[String]]::new()

# loops...

$failedTests.Add((Generate-FullyQualifiedName -etc))

You also don't need to loop through each step either to check if a scenario failed:

foreach($scenario in $feature.elements) {
  # -- Skip foreach $step
  if($scenario.steps.result.status -eq 'Failed') {
    $failedTests.Add((Generate-FullyQualifiedName -etc))
  }
}

For most purposes, I would stick with the looping you're doing. Depending on how huge each object actually is, it can be a little faster (and uglier) to iterate on an array index int instead of assigning the whole $feature object to a variable, but I doubt it would help much here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM