Advertisement
Guest User

utils

a guest
Sep 22nd, 2017
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.26 KB | None | 0 0
  1. """
  2. Test REST endpoint utility.
  3. Usage example:
  4. template file extension must be .yml
  5.  
  6. Ex template:
  7.  
  8. template: test_user.yml
  9.    - message: Add user
  10.      method: POST
  11.      endpoint: /add/user
  12.      payload:
  13.        username: Admin
  14.        password: admin
  15.      response:
  16.        $.username: Admin
  17.        $.password: admin
  18.  
  19. That template will result in POST request at URL/add/user
  20. with a payload '{username: Admin, password: admin}'
  21. And then it will check response as defined it check_response()
  22. Response will be checked not just for HTTP codes, but for
  23. values in responses too.
  24.  
  25. For this example response will be searched for username key under
  26. the document root. If value under key is the same as mapped value
  27. no exception will be raised. Otherwise, AssertionException will
  28. be raised.
  29.  
  30. All template files are 'executed' asynchronous, but tests inside templates
  31. are 'executed' one after another, from top to bottom.
  32. """
  33. from unittest import TestCase
  34.  
  35. import os
  36.  
  37. import yaml
  38. from jsonpath_rw import jsonpath, parse
  39. from requests import Session, Request, Response
  40. from rx import Observable
  41. """
  42. Path to directory with templates
  43. """
  44. template_dir = "templates"
  45. """
  46. REST service URL
  47. """
  48. url = "http://localhost:8080"
  49.  
  50.  
  51. def is_template(string: str):
  52.     return string.endswith(".yml")
  53.  
  54.  
  55. def get_templates():
  56.     templates = []
  57.     Observable.from_(os.listdir(template_dir)) \
  58.         .filter(is_template) \
  59.         .subscribe(templates.append)
  60.     return templates
  61.  
  62.  
  63. def template_as_yaml(template: str):
  64.     with open(template_dir + "/" + template) as stream:
  65.         return yaml.load(stream)
  66.  
  67.  
  68. def prepare_request_from(template: dict):
  69.     method = template.get("method", "")
  70.     endpoint = url + template.get("endpoint", "")
  71.     payload = template.get("payload", {})
  72.     return {"request": Request(method, endpoint, json=payload), "template": template}
  73.  
  74.  
  75. def prepare_requests(templates: list):
  76.     return [prepare_request_from(template) for template in templates]
  77.  
  78.  
  79. def execute_request(request: dict, session: Session):
  80.     req = request.get("request")
  81.     response = session.send(session.prepare_request(req))
  82.     return {"template": request.get("template"),
  83.             "method": req.method, "url": req.url,
  84.             "payload": req.json, "response": response}
  85.  
  86.  
  87. def execute_requests(request_list: list):
  88.     session = Session()
  89.     return [execute_request(request, session) for request in request_list]
  90.  
  91.  
  92. def check_response(response: dict):
  93.     code_msg = "response code not correct {} on {}.\n Should be in {} but was {}"
  94.     template: dict = response.get("template", {})
  95.     req_resp: dict = template.get("response", None)
  96.     assert response is not None, "processing error"
  97.     assert response["response"] is not None, "response is empty"
  98.     resp: Response = response["response"]
  99.     correct_codes = ()
  100.     if response["method"] == "POST":
  101.         correct_codes = (201, 200, 422)
  102.     if response["method"] == "GET":
  103.         correct_codes = (200,)
  104.     if response["method"] == "DELETE":
  105.         correct_codes = (200,)
  106.     if response["method"] == "PUT":
  107.         correct_codes = (200, 201)
  108.  
  109.     assert resp.status_code in correct_codes, code_msg.format(response["method"], response["url"],
  110.                                                               correct_codes, resp.status_code)
  111.  
  112.     if req_resp is not None:
  113.         for key, value in req_resp.items():
  114.             expr: jsonpath.Child = parse(key)
  115.             match = expr.find(resp.json())[0].value
  116.             assert match == value
  117.  
  118.     print("###\n{} with response code {}, {} on {}".format(template["message"],
  119.                                                            resp.status_code, response["method"], resp.url))
  120.     print("# response: \n{}".format(resp.text))
  121.  
  122.  
  123. class RestTests(TestCase):
  124.     templates = []
  125.     request_list = []
  126.     session = Session()
  127.  
  128.     @classmethod
  129.     def setup_class(cls):
  130.         Observable \
  131.             .from_(get_templates()) \
  132.             .map(template_as_yaml) \
  133.             .map(prepare_requests) \
  134.             .subscribe(cls.request_list.append)
  135.  
  136.     def test_requests(self):
  137.         Observable \
  138.             .from_(self.request_list) \
  139.             .flat_map(execute_requests) \
  140.             .subscribe(check_response)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement