def test_with_index_file(): eq(tb_m.obj5.get_value(), 22) eq(tb_m.obj6.get_value(), 17) eq(tb_m.obj6.get_msg(), 'Goodafternoon') #eq(tb_m.obj6.multiple(10), 170) check("tb_m.obj6.multiple(10) == 170") check("tb_m.obj6.multiple(10) == 20", warning=True, repeat=2)
def test_without_init(): eq(tb_m.obj7.get_value(), 1) eq(tb_m.obj7.get_value(), 2)
def test_with_paramoption_in_class(): eq(tb_m.obj3.get_msg(), 'Goodafternoon') eq(tb_m.obj4.get_msg(), 'Goodqq')
def test_with_param_in_class(): eq(tb_m.obj2.get_value(), 17) eq(tb_m.obj2.multiple(10), 170) eq(tb_m.obj2.get_value(), 170)
def test_with_param_in_func(): #tb_m = init_testbed("lesson8_testbed_obj.yaml") eq(tb_m.obj1.ppp2(3, 5), 8) ne(tb_m.obj1.ppp2(100, 20), 102) eq(tb_m.obj1.ppp2(4, 6, 10), 20)
def test_api_endpoints(test_data): """ common REST API test logic that hits a given endpoint and checks actual results against what's expected Args: test_data (dict): blocks of test parameters supplied one at a time by the test_data fixture 'retained_responses' (dict): when multiple requests are made by a test, this allows a preceding request to pass server response values to this allows a preceding request to pass server response values to subsequent calls Returns: """ test_logger.info("test_data is: {}", test_data) # eject if caller wants to skip this test if test_data['skip']: return # check for retained responses from previous calls. this is used to allow # subsequent requests to access a resource created by a previous one. # values that are saved for a subsequent GET request are assumed to be path # parameters and are appended to the URL as such. values that are saved for # POST requests are appended to the body of the request object. if 'retained_responses' in test_data: for http_verb, retained_response_kv_dict \ in test_data['retained_responses'].items(): if http_verb == 'GET': for e in retained_response_kv_dict: for k, v in e.items(): new_url = test_data['url'] + '/' + str(v) test_logger.info("updating url to: " + new_url) test_data['url'] = new_url elif http_verb == 'POST': for e in retained_response_kv_dict: for k, v in e.items(): test_logger.info( "adding %s %s to body of POST request " % (k, v)) test_data['payload'][k] = v # make request to server test_logger.info("REQUEST PURPOSE: " + test_data['purpose']) test_logger.info("test_data is: " + str(test_data)) request_dict = get_request_dict() http_verb = test_data['http_verb'] # if need be resolve file name string to actual file object # don't forget that type(http_verb) is unicode, not str so '==' # instead of 'is' !! if http_verb == 'POST' and len(test_data['files']) is not 0: filename = path.join(path.dirname(path.abspath(__file__)), str(test_data['files']['file'])) print('FILENAME', filename) test_data['files']['file'] = open(filename, 'rb') # nest payload dicts # format selected_path key if exists # might be able to remove with flask depending on how payloads are parsed if http_verb == 'POST' and 'selected_path' \ in test_data['payload']: test_data['payload']['selected_path'] = \ json.dumps(test_data['payload']["selected_path"]) test_data = get_test_data_clone_with_cookie_object(test_data) response = request_dict[http_verb](test_data) try: test_logger.debug("server response is: " + json.dumps(response.json(), indent=2)) except: test_logger.warn("not logging server response, probably because it's " "a file object...") # check explicit actual v expected server responses eq(response.status_code, test_data['expected_response_status_code'], "server should respond with HTTP OK") response_content_type = response.headers['Content-Type'] eq(response_content_type, test_data['expected_response_headers_content_type'], "content type should match expected") expected_response_json = test_data['expected_response_json'] # because the download endpoint doesn't return json if response_content_type == 'text/csv; charset=utf-8': actual_response_json = {} else: actual_response_json = response.json() # b/c response to a GET request vs process id is sometimes a nested dict if 'process' in actual_response_json and \ isinstance(actual_response_json['process'], dict): actual_response_json = actual_response_json['process'] if isinstance(expected_response_json, list): # for many of the test cases we're only able to check for # a subset of the kv pairs a given endpoint plops out. moreover the # server can't be counted on to return things in a predictable order. # therefore, in order to efficiently perform comparison, we're going to # figure out what kv pairs we're expecting and remove the remainder # from what the endpoint returns. actual_response_json_subsets = \ remove_extraneous_keys_from_actual_response( expected_response_json, actual_response_json) for e in expected_response_json: ok( e in actual_response_json_subsets, "server response should contain expected server response: " + str(actual_response_json_subsets) + " " + str(e)) else: for k in expected_response_json: eq(actual_response_json[k], expected_response_json[k], "server response should match expected server response") # check type-check-only values # # *NOTE* this works because it assumes that there won't be a case where # we're doing these kinds of type-only checks when actual_response_json is # list. if that changes this (and probably the above block as well) # will need to be refactored if len(test_data['expected_response_json_type_check']) is not 0: type_dict = get_type_dict() for k, v in test_data['expected_response_json_type_check'].items(): actual_response_value = actual_response_json[k] expected_type = type_dict[v] eq( type(actual_response_value), expected_type, "server response type should match " "expected server response type") # build retained_responses dict for subsequent requests. # # *NOTE* this block assumes that actual_response_json is a dict, # not a list. retained responses, if any, will be transformed into: # { # HTTP_VERB : [ {retained_response_key: retained_response_value}, ...] # } retained_responses = {} # b/c for some reason python interprets an empty {} in a json block a list retain_response_keys = dict(test_data['retain_response_keys']) # what a given REST call returns may not map to the same k,v pair a # subsequent call is expecting. this block reads the test parameter file # and makes the appropriate translation for http_verb, retain_response_key_dict in retain_response_keys.items(): retained_response_kv_list = [] for response_key, subsequent_request_key in \ retain_response_key_dict.items(): test_logger.info(actual_response_json) retained_response_element = { subsequent_request_key: actual_response_json[response_key] } retained_response_kv_list.append(retained_response_element) retained_responses[http_verb] = retained_response_kv_list # if present execute follow-up request subsequent_request = test_data['subsequent_request'] if len(subsequent_request) is not 0: subsequent_request['retained_responses'] = retained_responses if len(test_data['cookies']) is 0: subsequent_request['cookies'] = response.cookies else: subsequent_request['cookies'] = test_data['cookies'] test_api_endpoints(subsequent_request)