def run_test(f, ignores=[], raise_errors=True): """ Runs the test required for the test file. Params ====== f: str The name of the test file. ignores: list of int The index of the case to ignore """ # Ensure that #ignores# is a list if type(ignores) == type(1): ignores = [ignores] # Extract arguments cases = get_test_vals(f) # Loop through args and ans for cx, c in enumerate(cases): # If cx is in #ignores#, we ingore it if cx in ignores: continue # Unpack arguments and answers args = c['-arg'] ans = c['-ans'] # Repackage into string args = '\n'.join(args) ans = '\n'.join(ans) # Instantiate fnc arguments fnc.set_inputs(args) # Get start time start_time = datetime.now() # Run function try: try: fo(TIME_LIMIT, fnc.main, (args, )) # fnc.main(args) except FunctionTimedOut as e: raise e except Exception as e: raise e # Check answers assert "\n".join(fnc.fptr.get_answers()) == ans except Exception as e: c['error'] = e except FunctionTimedOut as e: c['error'] = e # Get time taken c['time_taken'] = datetime.now() - start_time # Give conclusions about each test case # Loop through cases to check for errors for cx, c in enumerate(cases): # Check for ignores if cx in ignores: continue print(f"\ntest case {str(cx)}: {str(c['time_taken'])}") for c in cases: # Only print errors if requested if raise_errors: try: raise c['error'] except KeyError as e: # Suggests there are no errors continue
def run_test(f, dcstr=[], dcix=[], raise_errors=True): """ Runs the test required for all cases within the folder. Any cases within dcstr and dcix are ignored. Params ====== f: str The name of the test folder. dcstr: [] Array of strings. If the element of dcstr is an exact match with any of the case file names, the case is ignored. dcix: [] Array of integers. Less reliable 'ignore' method. This ignores the 0-indexed element of the collected cases. raise_errors: bool Whether any errors gathered while testing the cases should be returned. If false, only whether a case succeeded or failed is returned. """ # === Ensure that dcstr and dcix are lists === # Check if dcstr is a list if type(dcstr) == type([]): # If it is a list, we identify if all elements are of type 'str' # Filter out all non-string types other_types = [type(x) for x in dcstr] other_types = list(set(other_types)) other_types = list(filter(lambda x: x != type(""), other_types)) # If there are non-string types, raise an exception if other_types: raise Exception(f"dcstr must be a list of strings. Elements of type {other_types} found.") # If it's not a list, check if it's a string elif type(dcstr) == type(""): # Set it to a list of string dcstr = [dcstr] # If it is neither a string or a list, we reject it. else: raise Exception(f"dcstr must be a string or a list of strings, not a {str(type(dcstr))}.") # We do the same check for dcix if type(dcix) == type([]): # If it is a list, we identify if all elements are of type 'str' # Filter out all non-string types other_types = [type(x) for x in dcix] other_types = list(set(other_types)) other_types = list(filter(lambda x: x != type(1), other_types)) # If there are non-string types, raise an exception if other_types: raise Exception(f"dcstr must be a list of integers. Elements of type {other_types} found.") # If it's not a list, check if it's a string elif type(dcix) == type(1): # Set it to a list of string dcix = [dcix] # If it is neither a string or a list, we reject it. else: raise Exception(f"dcix must be an integer or a list of integers, not a {str(type(dcix))}.") # === Get cases from the folder === cases = None try: # Obtain cases cases = get_cases(f) except AssertionError: raise Exception(f"The path '{f}' is not a valid folder.") # Ensure there are cases to run through if not cases: raise Exception(f"There are no test cases in '{f}'.") # === Loop through each case === for cx, c in enumerate(cases): # If cx is in dcix, ignore this case # If the name of the case is in dcstr, we ignore the case if cx in dcix or c["filename"] in dcstr: continue # Print out test case print(f"({f}) test case {cx} '{c['filename']}': ", end="") # Instantiate fnc arguments fnc.set_inputs(c["inputs"]) # Get start time start_time = datetime.now() # Run function try: fto( TIME_LIMIT, fnc.main, (c["inputs"], ) ) # If the function times out, add it as an error except FunctionTimedOut as e: c["errors"] = e # For any other exception, we also add it as an error # The reason we separate FunctionTimedOut from Exception is because FunctionTimedOut is not considered an Exception by the program except Exception as e: c["errors"] = e # Here, we check if there are errors if "errors" in c.keys(): # If there are errors, print the error out print(c["errors"]) else: # If there are no exceptions, we check that the answer is correct try: assert "\n".join(fnc.fptr.get_answers()) == c["outputs"] print("Success") except Exception as e: # There are, as of now, no errors # We set the errors to the assertion error c["errors"] = e # Print the error print(e) # Finally, we raise all errors so py.test recognises that this test case failed for c in cases: if "errors" in c.keys(): raise c["errors"]