使用 suds 库在 RobotFramework 中测试 Soap 1.2 服务

Testing Soap 1.2 service in RobotFramework using suds library

我正在尝试使用 RobotFramework 测试 soap 1.2 服务。到目前为止,我们只测试了使用 RobotFramework 的 suds 库的 soap 1.1 服务,suds 与 soap 1.2 不兼容。

向后兼容是新服务的一个选项,但最好有一个更长期的解决方案。我不是一个经验丰富的程序员,但如果告诉我编辑什么和在哪里我可以编辑代码。

我们对使用 suds 的 soap 1.2 服务进行的测试中发生的情况是:suds 无法解释它从 web 服务获得的响应并给出此错误:SAXParseException::159:229: 不匹配的标签

soap消息没问题,在SoapUI中使用没有问题

我在网上找到了一些片段,它们建议我可以让 suds 库与 soap 1.2 一起用于我的 RobotFramework 测试。但是我没有什么编程经验,也不知道如何将这些片段合并到 suds 中。 有人评论说这个片段解决了他的 RobotFramework 和 suds 问题。

有没有人愿意解释我如何才能完成这项工作?我似乎无法自己弄清楚。任何建议将不胜感激。

from suds.client import Client
from suds.bindings import binding
import logging


USERNAME = 'username'
PASSWORD = 'password'

# Just for debugging purposes.
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)

# Telnic's SOAP server expects a SOAP 1.2 envelope, not a SOAP 1.1 envelope
# and will complain if this hack isn't done.
binding.envns = ('SOAP-ENV', 'http://www.w3.org/2003/05/soap-envelope')
client = Client('client.wsdl',
        username=USERNAME,
        password=PASSWORD,
        headers={'Content-Type': 'application/soap+xml'})

# This will now work just fine.
client.service.someRandomMethod()

片段来自:https://gist.github.com/kgaughan/858851

简而言之,Suds 不支持 SOAP 1.2 绑定。开发已经停止很久了。因此 SudsLibrary 也不支持它。

我使用 example service SOAP 1.1/1.2 观察到的一些差异是:

  1. HTTP header Content-Type:
    • 1.2 = "application/soap+xml"
    • 1.1 = "text/xml".
  2. HTTP header
    • 1.2 = Action
    • 1.1 = SOAPAction
  3. Envelope Namespace
    • 1.2 = "http://www.w3.org/2003/05/soap-envelope"
    • 1.1 = "http://schemas.xmlsoap.org/soap/envelope/"

对于其中的每一个,在下面的示例中都实施了单独的解决方案。内容类型可能被覆盖。可以添加 Action,但不能删除 SOAPAction。也可以使用扩展库覆盖命名空间。如果您的服务忽略了 SOAPaction header 属性,这应该对您有用。

测试Case.robot

*** Settings ***
Library    SudsLibrary
Library    SudsLibraryExtension
Library    Collections    

*** Test Cases ***
TC
    ${BASE_URL}    Set Variable         http://www.holidaywebservice.com
    ${SERVICE}     Create Dictionary    
    ...                                 name=HolidayService_v2    
    ...                                 wsdl=HolidayService2.asmx?WSDL
    ${PORT}        Set variable         HolidayService2Soap12
    ${METHOD}      Set variable         GetCountriesAvailable

    Set Binding     SOAP-ENV    http://www.w3.org/2003/05/soap-envelope
    Create Soap Client     ${BASE_URL}/${SERVICE.name}/${SERVICE.wsdl}
    Set Port    ${PORT}

    Set Headers    Content-Type    application/soap+xml
    Set Headers    Soapaction      ${EMPTY}
    Set Headers    Action          "${BASE_URL}/${SERVICE.name}/${METHOD}"

    ${result}          Call Soap Method     ${METHOD}

SudsLibraryExtension.py

import suds.bindings
from robot.libraries.BuiltIn import BuiltIn, RobotNotRunningError

class SudsLibraryExtension(object):
    """
    Extension on the SudsLibrary

    """
    ROBOT_LIBRARY_SCOPE = 'GLOBAL'    
    ROBOT_LIBRARY_VERSION = 1.0

    def __init__(self, LibraryName='SudsLibrary'):
        """SudsLibraryExtension can be imported with an optional argument.
        - ``LibraryName``:
          Default value for `LibraryName` is SudsLibrary if not given.
          The name can by any Library Name that implements or extends the
          SudsLibraryExtension.
        """        
        try:
            self.SudsLibrary = BuiltIn().get_library_instance(LibraryName)

        # This is useful for when you run Robot in Validation mode or load
        # the library in an IDE that automatically retrieves the documen-
        # tation from the library. 
        except RobotNotRunningError:
            pass

    def set_binding(self, binding, url):
        """Set Binding can be used to add a binding to the message.

        Example    Set Binding     SOAP-ENV    http://www.w3.org/2003/05/soap-envelope
        """
        suds.bindings.binding.envns = (binding, url)