Как отправить XML в теле сообщения POST с помощью RobotFramework RESTInstance - PullRequest
0 голосов
/ 09 июня 2018

Я пытаюсь отправить запрос POST, используя RobotFramework, где тело запроса - XML.

Вот пример файла робота:

*** Settings ***
Library    REST

*** Variables ***
${SERVER_URL}    https://www.w3schools.com/xml/tempconvert.asmx

*** Test Cases ***
CL 1
    [Tags]    TC-CL
#    Send SOAP via POST    <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">" <soap:Body>" <FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/">" <Fahrenheit>100</Fahrenheit>" </FahrenheitToCelsius>" </soap:Body>"</soap:Envelope>
#    Send SOAP via POST    <?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <FahrenheitToCelsius xmlns=\"https://www.w3schools.com/xml/\">\" <Fahrenheit>100</Fahrenheit> </FahrenheitToCelsius> </soap:Body></soap:Envelope>
#    Send SOAP via POST    <?xml version=\"1.0\" encoding=\"utf-8\"?>\n<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <soap:Body>\n <FahrenheitToCelsius xmlns=\"https://www.w3schools.com/xml/\">\n <Fahrenheit>100</Fahrenheit>\n </FahrenheitToCelsius>\n </soap:Body>\n</soap:Envelope>
    Send SOAP via POST    <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/"><Fahrenheit>100</Fahrenheit></FahrenheitToCelsius></soap:Body></soap:Envelope>


*** Keywords ***
Send SOAP via POST
    [Arguments]         ${body}
    SET HEADERS    {"SOAPAction": "https://www.w3schools.com/xml/FahrenheitToCelsius","Content-Type": "text/xml","Cache-Control": "no-cache"}

    ${resp}=    POST    ${SERVER_URL}    data=${body}
    Log    ${resp}  repr=true

Когда вы запускаете этот код, яполучить ошибку:

This is not a JSON string:
"data=<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/
soap/envelope/"><soap:Body><FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/"><Fahrenheit>100</Fahrenheit></FahrenheitToCelsius></soap:Body></soap:Envelope>"

К вашему сведению: закомментированные версии «Отправка SOAP через POST» - это разные способы, которыми я пытался обойти проблему.

Вот пример кода Python с использованием запросовчтобы убедиться, что моя конечная точка работает (как только я обойду это надоедливое «Это не проблема строки JSON»:

import requests

url = "https://www.w3schools.com/xml/tempconvert.asmx"

payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n  <soap:Body>\r\n   <FahrenheitToCelsius xmlns=\"https://www.w3schools.com/xml/\">\r\n     <Fahrenheit>100</Fahrenheit>\r\n   </FahrenheitToCelsius>\r\n  </soap:Body>\r\n</soap:Envelope>"
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <FahrenheitToCelsius xmlns=\"https://www.w3schools.com/xml/\">\" <Fahrenheit>100</Fahrenheit> </FahrenheitToCelsius> </soap:Body></soap:Envelope>"
payload = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/"><Fahrenheit>100</Fahrenheit></FahrenheitToCelsius></soap:Body></soap:Envelope>'
headers = {
    'SOAPAction': "\"https://www.w3schools.com/xml/FahrenheitToCelsius\"",
    'Content-Type': "text/xml",
    'Cache-Control': "no-cache",
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)

Проблема, похоже, заключается в коде RESTInstance здесь

Первоначальная проблема, которая вызывает ошибку (см. Строку комментариев ниже):

@keyword
def post(self, endpoint, body=None, timeout=None, allow_redirects=None,
         validate=True, headers=None):
    """Make a ``POST`` request call to a specified ``endpoint``.
    Example:
    POST "Mr Potato" to endpoint and ensure status code is 201
    | `POST`    | /users          | { "id": 11, "name": "Mr Potato" } |
    | `Integer` | response status | 201                               |
    """
    endpoint = self._input_string(endpoint)
    request = deepcopy(self.request)
    request['method'] = "POST"
    request['body'] = self.input(body)  # <== ERROR THROWS HERE
    if allow_redirects is not None:
        request['allowRedirects'] = self._input_boolean(allow_redirects)
    if timeout is not None:
        request['timeout'] = self._input_timeout(timeout)
    validate = self._input_boolean(validate)
    if headers:
        request['headers'].update(self._input_object(headers))
    return self._request(endpoint, request, validate)['response']

Основная проблема заключается в том, что код _request заставляет использовать тело в параметре json файла request.requests.call (он же клиент основан на импорте), см. фрагмент кода из того же файла ниже:

def _request(self, endpoint, request, validate=True):
    if endpoint.endswith('/'):
        endpoint = endpoint[:-1]
    if not endpoint.startswith(('http://', 'https://')):
        base_url = self.request['scheme'] + "://" + self.request['netloc']
        if not endpoint.startswith('/'):
            endpoint = "/" + endpoint
        endpoint = urljoin(base_url, self.request['path']) + endpoint
    request['url'] = endpoint
    url_parts = urlparse(request['url'])
    request['scheme'] = url_parts.scheme
    request['netloc'] = url_parts.netloc
    request['path'] = url_parts.path
    try:
        response = client(request['method'], request['url'],
                          params=request['query'],
                          json=request['body'],    #<== ROOT CAUSE HERE
                          headers=request['headers'],
                          proxies=request['proxies'],
                          cert=request['cert'],
                          timeout=tuple(request['timeout']),
                          allow_redirects=request['allowRedirects'],
                          verify=request['sslVerify'])

При отправке XML с использованием библиотеки запросов вам нужно использовать body = not json =

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...