sudsLibrary Soap Method calls with optional arguments

461 views
Skip to first unread message

yahman72

unread,
Nov 3, 2014, 9:49:03 AM11/3/14
to robotframe...@googlegroups.com
Howdy, 

I'm trying trying to figure out a way to pass optional arguments to a Soap Method, but don't get it working ...

Assume a wsdl.
         <s:element name="DoIt">
            <s:complexType>
               <s:sequence>
                  <s:element minOccurs="0" maxOccurs="1" name="arg1" type="tns:MyType"/>
                  <s:element minOccurs="0" maxOccurs="1" name="arg2" type="tns:MyType"/>
               </s:sequence>
            </s:complexType>
         </s:element>

Now I would like to execute the following method calls:
Do(arg1=abc)
Do(arg2=def)
Do(arg1=abc, arg2=def)

How should I call the "Call Soap Method" in sudsLibrary to make this work?


I have tried all kinds of variations of passing the arguments but it the generated SOAP message is always wrong e.g.
a) passing the argument names in the call method e.g.
Call Soap Method    DoIt   arg1   abc    arg2   def
Call Soap Method    DoIt   arg1=abc    arg2=def
--> but this does not work, the arguments are used a positional when generating the SOAP e.g.
    <ns0:DoIt>
      <ns0:arg1>arg1</ns0:arg1>
      <ns0:arg2>abc</ns0:arg2>
    </ns0:DoIt>
and
    <ns0:DoIt>
      <ns0:arg1>arg1=abc</ns0:arg1>
      <ns0:arg2>arg2=def</ns0:arg2>
    </ns0:DoIt>

b) passing WSDL object as argument
${a}=     Create Wsdl Object  DoIt   arg1   abc   arg2   def
${resp}=  Call Soap Method    DoIt   ${a}
--> but this does not work, the WSDL object is inserted into the first argument e.g.
    <ns0:DoIt>
      <ns0:arg1>
        <ns0:arg1>abc</ns0:arg1>
        <ns0:arg2>def</ns0:arg2>
      </ns0:arg1>
      <ns0:arg2>arg2=def</ns0:arg2>
    </ns0:DoIt>

c) Calling the method with empty arguments e.g.
Call Soap Method    DoIt   abc   ${EMPTY}
Call Soap Method    DoIt   ${EMPTY}   def   
--> but this does not work, the optional arguments are still in the request without values e.g.
    <ns0:DoIt>
      <ns0:arg1>abc</ns0:arg1>
      <ns0:arg2/>
    </ns0:DoIt>

I'm using suds (0.4) and sudslibrary (0.8)....

Kevin O.

unread,
Nov 4, 2014, 9:39:37 AM11/4/14
to robotframe...@googlegroups.com
Named arguments definitely will not work, but you should be able to pass None to skip any arguments with defaults that precede the one(s) you want to pass. In RF, you use the automatically defined variable ${None} to pass None.
There is no need to pass any arguments after the last one you are overriding the default.
Call Soap Method    DoIt   abc   ${EMPTY}
could just be
    Call Soap Method    DoIt   abc
although this will work as well:
    Call Soap Method    DoIt   abc   ${None}

I created a web service with optional args and was able to do what you are trying to do. My test, code, and some output are at the end of this message.

kwargs support could be added to the library, but it would have the downside of breaking any test that has a '=' in the argument value since '=' has to be escaped.

Foo
    Create Soap Client    ${TEST WSDL URL}
    ${sum}    Call Soap Method    foo    ${None}    42    # skipping argument named "a" with default of 1
    Should Be Equal As Numbers    ${sum}    43
    ${sum}    Call Soap Method    foo    5
    Should Be Equal As Numbers    ${sum}    7

    @ladonize(PORTABLE_STRING, PORTABLE_STRING, rtype=int)
    def foo(self, a=u"1", b=u"2"):
        return int(a) + int(b)

<wsdl:message name="foo">
<wsdl:part name="a" type="xsd:string"/>
<wsdl:part name="b" type="xsd:string"/>
</wsdl:message>

Extracted output from the test (1st call):
<ns2:Body> <ns1:foo> <b xsi:type="ns3:string">42</b> </ns1:foo> </ns2:Body>

Extracted output from the test (2nd call):
<ns2:Body> <ns1:foo> <a xsi:type="ns3:string">5</a> </ns1:foo> </ns2:Body>
Reply all
Reply to author
Forward
0 new messages