使用Robot Framework中的SUDS库和MessagePlugin创建带有objectTypes的Soap消息

时间:2016-07-27 08:32:18

标签: soap robotframework suds

这是此问题的延续:Creating Soap messages with objectTypes using SUDS library in Robot Framework

在那里确定使用RF SUDS不可能仅使用SUDS创建具有objectTypes的消息。我想尝试MessagePlugin方法,但遗憾的是文档中的信息对我来说还不够:

from robot.libraries.BuiltIn import BuiltIn
from suds.plugin import MessagePlugin

class _MyPlugin(MessagePlugin):
    def marshalled(self, context):
        body = context.envelope.getChild('Body')
        foo = body[0]
        foo.set('id', '12345')
        foo.set('version', '2.0')

class SudsLibraryExtensions(object):
    def attach_my_plugin(self):
        client = BuiltIn().get_library_instance("SudsLibrary")._client()
        # prepend so SudsLibrary's plugin is left in place
        plugins = client.options.plugins
        if any(isinstance(x, _MyPlugin) for x in plugins):
            return
        plugins.insert(0, _MyPlugin())
        client.set_options(plugins=plugins)

有没有人有关于如何使用上述代码段的完整机器人示例?我应该把什么作为背景进行编组?我是否需要在某个时候调用attach_my_plugin()?

1 个答案:

答案 0 :(得分:1)

可以在Suds documentation中找到消息插件的一般说明。更多详情请见class documentation。你没有打电话,肥皂水。为了更好地理解如何实现编组方法,请阅读Element的文档。 suds插件本质上是一个监听器。我的示例使用公共Web服务进行演示。

说出您的请求如下:

...
<ns0:Body>
    <ns1:GetStatistics>
      <ns1:X>
...

但你需要它看起来像这样:

....
<ns0:Body>
    <ns1:GetStatistics type="specialType">
      <ns1:X>
 ...

这是一个将type属性添加到GetStatistics元素的插件。当元素具有子元素和发送的属性时,这可能是必要的。 Suds 0.4不支持这个,但它是有效的SOAP。可能有一个支持这个的Suds分支。

*** Settings ***
Library           SudsLibrary
Library           c:/SudsLibraryExtensions.py

*** Test Cases ***
Message Plugin
    Create Soap Client    http://www.webservicex.net/Statistics.asmx?WSDL
    Attach My Plugin
    Set GetStats Type    specialType
    ${dbl array}=    Create Wsdl Object    ArrayOfDouble
    Append To List    ${dbl array.double}    2.0
    Append To List    ${dbl array.double}    3.0
    ${result}=    Call Soap Method    GetStatistics    ${dbl array}
    Should Be Equal As Numbers    ${result.Average}    2.5

c:/SudsLibraryExtensions.py的内容:

from robot.libraries.BuiltIn import BuiltIn
from suds.plugin import MessagePlugin

class _MyPlugin(MessagePlugin):

    def __init__(self):
        self._type = 'defaultType'

    def marshalled(self, context):
        body = context.envelope.getChild('Body')
        call = body.getChild('GetStatistics')
        call.set('type', self._type)

    def set_getstats_type(self, value):
        self._type = value

class SudsLibraryExtensions(object):
    def attach_my_plugin(self):
        client = BuiltIn().get_library_instance("SudsLibrary")._client()
        plugins = client.options.plugins
        if any(isinstance(x, _MyPlugin) for x in plugins):
            return
        # prepend so SudsLibrary's plugin is left in place
        plugins.insert(0, _MyPlugin())
        client.set_options(plugins=plugins)

    def set_getstats_type(self, value):
        self._get_plugin().set_getstats_type(value)

    def _get_plugin(self):
        client = BuiltIn().get_library_instance("SudsLibrary")._client()
        plugins = client.options.plugins
        my_plugin = next((plugin for plugin in plugins if isinstance(plugin, _MyPlugin)), None)
        if my_plugin is None:
            raise RuntimeError("Plugin not found. Did you call Attach My Plugin?")
        return my_plugin

只要插件附加了关键字Attach My Plugin,就会始终设置type属性。有一个默认类型。要更改type的值,请使用关键字Set GetStats Type。任何类型集将在未来的所有请求中使用,直到更改为止。这里使用两个类的唯一原因是为了防止“编组”成为公开的关键字。