Web services 正在尝试比较web服务响应和文件中的预期xml

Web services 正在尝试比较web服务响应和文件中的预期xml,web-services,testing,powershell,Web Services,Testing,Powershell,我们在Java中开发的最多,但我们也希望将web服务与ms集成测试(使用)。为此,我正在编写连接到web服务的powershell脚本,并将响应与从文件加载的xml进行比较 [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} $instance = New-WebServiceProxy -Uri "https://localhost:7002/service?WSDL" -Namespa

我们在Java中开发的最多,但我们也希望将web服务与ms集成测试(使用)。为此,我正在编写连接到web服务的powershell脚本,并将响应与从文件加载的xml进行比较

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
$instance = New-WebServiceProxy -Uri "https://localhost:7002/service?WSDL" -Namespace "myspace"
$instance.Credentials = new-object System.Net.NetworkCredential("user", "pass")
...
$reply = $instance.fetchInformation($inputA, $inputB)
[xml]$expected = Get-Content ("expected.xml")
...
但是,现在我有了一个$reply,其中包含来自myspace命名空间的对象,还有一个$expected,其中包含一个XMLNode。我认为有两种方法可以做到这一点(可能还有更多):

  • 获取原始XML响应并进行比较。然而,我似乎不知道如何得到它
  • 将$expected XML序列化到myspace命名空间对象中。可能吗

  • 您可以将web服务返回的响应序列化为XML,并将其与
    expected.XML
    文件的内容作为字符串进行比较

    下面是一个例子:

    $writer = New-Object System.IO.StringWriter
    $serializer = New-Object System.Xml.Serialization.XmlSerializer($reply.GetType())
    $serializer.Serialize($writer, $reply)
    
    $replyAsXml = $writer.ToString()
    $expectedReplyAsXml = Get-Content expected.xml
    
    $replyAsXml -eq $expectedReplyAsXml
    

    请注意,在本例中,您需要确保
    expected.XML
    文件中包含的XML在间距和缩进方面与返回的XML匹配。为了避免这种情况,您可以在比较两个字符串之前从两个字符串中删除所有额外字符(如空格和换行符)。

    您可以将web服务返回的响应序列化为XML,并将其与
    expected.XML
    文件的内容作为字符串进行比较

    下面是一个例子:

    $writer = New-Object System.IO.StringWriter
    $serializer = New-Object System.Xml.Serialization.XmlSerializer($reply.GetType())
    $serializer.Serialize($writer, $reply)
    
    $replyAsXml = $writer.ToString()
    $expectedReplyAsXml = Get-Content expected.xml
    
    $replyAsXml -eq $expectedReplyAsXml
    

    请注意,在本例中,您需要确保
    expected.XML
    文件中包含的XML在间距和缩进方面与返回的XML匹配。为了避免这种情况,您可以在比较两个字符串之前从两个字符串中去掉所有额外的字符(如空格和换行符)。

    我最终采用了一种完全不同的方法。这两个XML彼此非常不同,因此我创建了一个自定义比较器。这使得我可以简单地编写自定义代码来忽略无趣的差异

    这导致了一些执行此任务的原始代码:

    # Assume two arrays of equal length
    Function Zip {
        Param($a1, $a2)
    
        $sum = New-Object object[] $a1.Count
        For ($i = 0; $i -lt $a1.Count; ++$i) {
            $sum[$i] = New-Object object[] 2
            $sum[$i][0] = $a1[$i]
            $sum[$i][1] = $a2[$i]
        }
        Return ,$sum
    }
    
    
    Function XmlChildNodes2List{
        param($nodes)
        $myArray = New-Object object[] 0
        For ($i = 0; $i -lt $nodes.Count; ++$i) {
            $node = $nodes.Item($i)
            If ($node -ne $null) {
                $myArray += $node
            }
        }
        Return ,$myArray
    }
    
    Function ShowContext{
        Param($ctx)
        " at " + $ctx
    }
    
    Function CompareNode{
        Param($o1, $o2, $ctx)
    
        Try {
        Switch ($o1.GetType().Name) {
            "XmlDocument" {
                CompareXml $o1.ChildNodes $o2.ChildNodes
            }
            "XmlChildNodes" {
                $olist1 = XmlChildNodes2List $o1 | Sort
                $olist2 = XmlChildNodes2List $o2 | Sort
                If ($olist1.Count -ne $olist2.Count) {
                    $msg = "Unequal child node count " + ($olist1 -join ",") + " and " + ($olist2 -join ",") + (ShowContext $ctx)
                    throw $msg
                } Else {
                    $list = Zip $olist1 $olist2
                    $value = $true
                    foreach ($item in $list) {
                        if ($value -eq $true) {
                            $value = CompareXml $item[0] $item[1] $ctx
                        }
                    }
                    $value
                }
            }
            "XmlElement" {
                If ($o1.LocalName -eq $o2.LocalName) {
                    If ($o1.LocalName -eq "uninterestingElement" -or $o1.LocalName -eq "uninterestingElement2") {
                        $true
                    } Else {
                        CompareXML $o1.ChildNodes $o2.ChildNodes ($ctx + "/" + $o1.LocalName)
                    }
                } Else {
                    throw ("Element " + $o1.LocalName + " != " + $o2.LocalName + (ShowContext $ctx))
                }
            }
            "XmlDeclaration" {
                $true
            }
            "XmlText" {
                $result = $o1.InnerText.Replace("`r`n","`n")
                $expect = $o2.InnerText.Replace("`r`n","`n")
                # TODO: Hack to remove timezone from expected dates in format 2005-09-01+02:00, the webservice side of the
                # reply to xml-conversion looses them
                If ($expect -match "^(\d{4}-\d\d-\d\d)\+\d\d:\d\d$") {
                    $expect = $Matches[1]
                }
                If ($result -eq $expect) {
                    $true
                } Else {
                    throw ($o1.InnerText + " is not equal to " + $o2.InnerText + (ShowContext $ctx))
                }
            }
            Default {
                throw ("What to do with node " + $o1.GetType().Name + (ShowContext $ctx))
            }
        }
        } Catch [Exception] {
            throw $_
        }
    }
    
    Function CompareXML{
        Param($o1, $o2, $ctx)
    
        If ($o1 -eq $null -and $o2 -eq $null) {
            $true
        } ElseIf ($o1 -eq $null -or $o2 -eq $null) {
            throw ("Response or expected is null")
        } ElseIf ($o1.GetType() -eq $o2.GetType()) {
            CompareNode $o1 $o2 $ctx
        } Else {
            throw ($o1.GetType().Name + " is not " + $o2.GetType().Name + (ShowContext $ctx))
        }
    }
    
    然后可以在如下两个XML上运行:

    CompareXML $result $expected ""
    

    我最终采用了完全不同的方法。这两个XML彼此非常不同,因此我创建了一个自定义比较器。这使得我可以简单地编写自定义代码来忽略无趣的差异

    这导致了一些执行此任务的原始代码:

    # Assume two arrays of equal length
    Function Zip {
        Param($a1, $a2)
    
        $sum = New-Object object[] $a1.Count
        For ($i = 0; $i -lt $a1.Count; ++$i) {
            $sum[$i] = New-Object object[] 2
            $sum[$i][0] = $a1[$i]
            $sum[$i][1] = $a2[$i]
        }
        Return ,$sum
    }
    
    
    Function XmlChildNodes2List{
        param($nodes)
        $myArray = New-Object object[] 0
        For ($i = 0; $i -lt $nodes.Count; ++$i) {
            $node = $nodes.Item($i)
            If ($node -ne $null) {
                $myArray += $node
            }
        }
        Return ,$myArray
    }
    
    Function ShowContext{
        Param($ctx)
        " at " + $ctx
    }
    
    Function CompareNode{
        Param($o1, $o2, $ctx)
    
        Try {
        Switch ($o1.GetType().Name) {
            "XmlDocument" {
                CompareXml $o1.ChildNodes $o2.ChildNodes
            }
            "XmlChildNodes" {
                $olist1 = XmlChildNodes2List $o1 | Sort
                $olist2 = XmlChildNodes2List $o2 | Sort
                If ($olist1.Count -ne $olist2.Count) {
                    $msg = "Unequal child node count " + ($olist1 -join ",") + " and " + ($olist2 -join ",") + (ShowContext $ctx)
                    throw $msg
                } Else {
                    $list = Zip $olist1 $olist2
                    $value = $true
                    foreach ($item in $list) {
                        if ($value -eq $true) {
                            $value = CompareXml $item[0] $item[1] $ctx
                        }
                    }
                    $value
                }
            }
            "XmlElement" {
                If ($o1.LocalName -eq $o2.LocalName) {
                    If ($o1.LocalName -eq "uninterestingElement" -or $o1.LocalName -eq "uninterestingElement2") {
                        $true
                    } Else {
                        CompareXML $o1.ChildNodes $o2.ChildNodes ($ctx + "/" + $o1.LocalName)
                    }
                } Else {
                    throw ("Element " + $o1.LocalName + " != " + $o2.LocalName + (ShowContext $ctx))
                }
            }
            "XmlDeclaration" {
                $true
            }
            "XmlText" {
                $result = $o1.InnerText.Replace("`r`n","`n")
                $expect = $o2.InnerText.Replace("`r`n","`n")
                # TODO: Hack to remove timezone from expected dates in format 2005-09-01+02:00, the webservice side of the
                # reply to xml-conversion looses them
                If ($expect -match "^(\d{4}-\d\d-\d\d)\+\d\d:\d\d$") {
                    $expect = $Matches[1]
                }
                If ($result -eq $expect) {
                    $true
                } Else {
                    throw ($o1.InnerText + " is not equal to " + $o2.InnerText + (ShowContext $ctx))
                }
            }
            Default {
                throw ("What to do with node " + $o1.GetType().Name + (ShowContext $ctx))
            }
        }
        } Catch [Exception] {
            throw $_
        }
    }
    
    Function CompareXML{
        Param($o1, $o2, $ctx)
    
        If ($o1 -eq $null -and $o2 -eq $null) {
            $true
        } ElseIf ($o1 -eq $null -or $o2 -eq $null) {
            throw ("Response or expected is null")
        } ElseIf ($o1.GetType() -eq $o2.GetType()) {
            CompareNode $o1 $o2 $ctx
        } Else {
            throw ($o1.GetType().Name + " is not " + $o2.GetType().Name + (ShowContext $ctx))
        }
    }
    
    然后可以在如下两个XML上运行:

    CompareXML $result $expected ""
    

    expected.xml
    包含什么?仅web服务返回的数据序列化为XML或整个SOAP响应?仅为SOAP响应的内容部分。
    expected.XML
    包含什么?只是由序列化为XML的web服务返回的数据还是整个SOAP响应?只是SOAP响应的内容部分。