Сравнивая результат Json из функции в роботе Framework
Попытка создать тестовый пример в рамках робота.
У нас есть пара остальных apis, которая возвращает нам Json как результат. Чтобы вызвать такой случай, мы использовали следующий код в rest2.py
def restJSON():
r = requests.get("http://httpbin.org/get")
# print "Code" , r.status_code
# print "Text " , r.text
return r.json()
Мы сохранили JSON внутри файла вывода. И мы написали тестовый пример робота для оценки сравнения JSON, как показано ниже
*** Settings ***
Library rest2.py
Library OperatingSystem
*** Test Cases ***
Example that calls a python keyword
${result}= restJSON
${json}= Get file output
Should be equal ${result} ${json}
Но когда мы запускаем тестовый пример Pybot, мы получаем ошибку, в которой говорится, что оба json не совпадают.
--------------------------------
pybot testSuite.txt
--------------------------------
==============================================================================
testSuite
==============================================================================
Example that calls a python keyword | FAIL |
{u'origin': u'10.252.30.94, 69.241.25.16', u'headers': {u'Via': u'1.1 localhost (squid/3.1.14)', u'Accept-Encoding': u'gzip, deflate, compress', u'Accept': u'*/*', u'User-Agent': u'python-requests/2.2.1 CPython/2.7.6 Linux/3.16.0-30-generic', u'Host': u'httpbin.org', u'Cache-Control': u'max-age=259200'}, u'args': {}, u'url': u'http://httpbin.org/get'} != {u'origin': u'10.252.30.94, 69.241.25.16', u'headers': {u'Via': u'1.1 localhost (squid/3.1.14)', u'Accept-Encoding': u'gzip, deflate, compress', u'Accept': u'*/*', u'User-Agent': u'python-requests/2.2.1 CPython/2.7.6 Linux/3.16.0-30-generic', u'Host': u'httpbin.org', u'Cache-Control': u'max-age=259200'}, u'args': {}, u'url': u'http://httpbin.org/get'}
------------------------------------------------------------------------------
testSuite | FAIL |
1 critical test, 0 passed, 1 failed
1 test total, 0 passed, 1 failed
==============================================================================
Файл JSON одинаков. Но все-таки его тест Failing говорит о том, что оба они не одинаковы. Это правильный способ сравнения, или у нас есть какой-то другой способ сделать это в среде роботов.
3 ответа
Почему бы не использовать уже существующие библиотеки:
Пример кода:
*** Settings ***
Library RequestsLibrary
Library Collections
Library XML use_lxml=True
Force Tags REST
*** Variables ***
${SERVICE_ROOT} http://ip.jsontest.com/
${SERVICE_NAME} testing
*** Keywords ***
json_property_should_equal
[Arguments] ${json} ${property} ${value_expected}
${value_found} = Get From Dictionary ${json} ${property}
${error_message} = Catenate SEPARATOR= Expected value for property " ${property} " was " ${value_expected} " but found " ${value_found} "
Should Be Equal As Strings ${value_found} ${value_expected} ${error_message} values=false
*** Test Cases ***
Example REST JSON
Create session ${SERVICE_NAME} ${SERVICE_ROOT}
${headers}= Create Dictionary Content-Type=application/json Accept=application/json
${result}= Get Request ${SERVICE_NAME} ${SERVICE_ROOT} headers=${headers}
Should Be Equal ${result.status_code} ${200}
Log ${result.content}
${json}= To Json ${result.content}
${pp}= To Json ${result.content} pretty_print=True
Log ${pp}
json_property_should_equal ${json} ip [Your_IP]
Не забудьте установить все необходимые библиотеки:
pip install robotframework-requests
pip install requests
Get File
читает содержимое файла и возвращает строку; в то же время функция python возвращает объект dict. Похоже, вы сравниваете dict со строкой - а они просто не могут вернуть равно.
Если вы преобразуете вывод файла в dict, то проверка, скорее всего, пройдет:
# your other code
${json_file}= Get file output
${json_file}= Evaluate json.loads("""${json_file}""") json # use the json module to transform str->dict
Should Be Equal ${result} ${json_file}
# even better - more verbose logging if values differ, or there are missing keys:
Dictionaries Should Be Equal ${result} ${json_file}
Каков ответ, когда вы делаете:
Should Be Equal As Strings ${result} ${json}
Я нахожу ваш метод достижения того, что вы хотите, немного странным, на вашем месте я бы использовал http-библиотеку или библиотеку запросов
https://github.com/peritus/robotframework-httplibrary https://github.com/bulkan/robotframework-requests
Рабочие примеры
поместите это в файл.robot
*** Settings ***
Library jsonlib.py
*** Variables ***
${response_json} {"key1": 33, "key2": "string", "key3": [1,2,3,"sring"], "name": "hans"}
${expected_json} {"key1": 77, "key2": "string", "key3": [1,2,3,"sring"], "name": "OTTO", "age": 33}
*** Test Cases ***
response meets expectation
&{json1}= Evaluate json.loads('''${response_json}''') json
&{json2}= Evaluate json.loads('''${expected_json}''') json
Log Dictionary ${json1}
Log Dictionary ${json2}
# ${type}= evaluate type(${json1}).__name__
# ${type}= evaluate type(&{json2})
response_meets_expectation ${json1} ${json2}
compare json payloads
&{json1}= Evaluate json.loads('''${response_json}''') json
&{json2}= Evaluate json.loads('''${expected_json}''') json
compare_json_payloads ${json1} ${json2}
json payloads should match
&{json1}= Evaluate json.loads('''${response_json}''') json
&{json2}= Evaluate json.loads('''${expected_json}''') json
json_paylodas_should_match ${json1} ${json2}
поместите это в jsonlib.py в той же папке, что и файл.robot
# -*- coding: utf-8 -*-
import json
import jsondiff
from deepdiff import DeepDiff
# from deepdiff import DeepSearch, grep
from pprint import pprint
from robot.api import logger
class JsonCompareError(Exception):
pass
def response_meets_expectation(response, expectation):
union = jsondiff.patch(response, expectation)
difference = jsondiff.diff(response, union)
if difference:
raise JsonCompareError("Diff found: {}".format(difference))
else:
return True
def compare_json_payloads(response_json, expected_json):
logger.debug("Compare JSON payloads")
diff = DeepDiff(response_json, expected_json, ignore_order=True, verbose_level=2)
logger.debug("Values changed: {}".format(diff['values_changed']))
return diff.to_dict()
def json_paylodas_should_match(response_json, expected_json):
diff = DeepDiff(response_json, expected_json, verbose_level=2)
if diff != {}:
raise JsonCompareError("Payloads do not match! Differences: {}".format(diff))
else:
return True
Используя https://github.com/Accruent/robotframework-zoomba это будет примерно так:
Library Zoomba.APILibrary
*** Test Cases ***
Example Test
${headers}= Create Dictionary Content-Type=application/json Accept=application/json
${actual_response}= Call Get Request ${headers} http://httpbin.org/get
Validate Response Contains Expected Response ${actual_response} ${expected_response}
Это будет проходить ключ за ключом для проверки результатов, все, что не получится, будет выглядеть так:
Key(s) Did Not Match:
------------------
Key: pear
Expected: fish
Actual: bird
------------------
Full List Breakdown:
Expected: [{'apple': 'cat', 'banana': 'dog', 'pear': 'fish'}, {'apple': 'cat', 'banana': 'mice', 'pear': 'bird'}, {'apple': 'dog', 'banana': 'mice', 'pear': 'cat'}]
Actual: [{'apple': 'cat', 'banana': 'dog', 'pear': 'bird'}]
Please see differing value(s)"
Документы здесь: https://accruent.github.io/robotframework-zoomba/docs/APILibraryDocumentation.html