Reporting test results as JSON and XML I have two functions now with very similar functionality, and would like to merge them into one more generic function. The only difference between those two functions is that one handles json input file and the other xml input file.
I could use if statements to achieve this, but I find it cumbersome, other suggestions would be much appreciated!

def update_json_type_report(self, testcase_id, did_any_test_fail, test_case_steps):
    print "Adding results to test case id: %s" % testcase_id

    fail_or_pass = '(/) ' # initialize test to pass

    expected_result = {
        "result":""
    }

    for i, step in enumerate(test_case_steps):
        for tests in self.parsed_report_file["suites"]:
            for test in tests["tests"]:
                tmp_result = ""
                if test["name"] == test_case_steps[i]['step']['raw'] and test["state"]:
                    if "error" in test:
                        fail_or_pass = '(x) '
                        did_any_test_fail = 3
                        tmp_result += fail_or_pass + test["error"] + '\n'
                    else:
                        # can have many tests per step, append them all in one string adding '\n' at end of each line
                        tmp_result += fail_or_pass + test["name"] + '\n'

                    break
            #import pdb; pdb.set_trace()
            expected_result['result'] = tmp_result
            if tmp_result: 
                self.jira_obj.send_put('xray', 'test/%s/steps/%s' % (testcase_id, test_case_steps[i]['id']), expected_result)

    return did_any_test_fail

def update_xml_type_report(self, testcase_id, did_any_test_fail, test_case_steps):
    print "Adding results to test case id: %s" % testcase_id

    fail_or_pass = '(/) ' # initialize test to pass

    expected_result = {
        "result":""
    }

    for i, step in enumerate(test_case_steps):
        for xml_testsuite in self.parsed_report_file:
            for xml_testcase in xml_testsuite.iter('testcase'):
                tmp_result = ""
                if xml_testcase.attrib["name"] == test_case_steps[i]['step']['raw'] and "hook" not in xml_testcase.attrib["name"]:
                    if xml_testcase.find('system-err') is not None:
                        fail_or_pass = '(x) '
                        did_any_test_fail = 3
                        tmp_result += fail_or_pass + xml_testcase.find('system-err').text + '\n'
                    else:
                        # can have many tests per step, append them all in one string adding '\n' at end of each line
                        tmp_result += fail_or_pass + xml_testcase.attrib["name"] + '\n'

                    break

            expected_result['result'] = tmp_result
            if tmp_result: 
                self.jira_obj.send_put('xray', 'test/%s/steps/%s' % (testcase_id, test_case_steps[i]['id']), expected_result)

    return did_any_test_fail
It looks like you need to abstract out how you get the element that contains the test cases and then how you determine errors from the nodes in the element.

for test in self.parsed_report_file["suites"]["tests"]: 

and 

for xml_testcase in xml_testsuite.iter('testcase'): 

get you the parent element to start the loop and then you need to determine whether the items are in error. I think it would make things easier if you did some of the refinement when you get the initial set of elements rather than doing more filtering in the loops. Since in the JSON case you only care about nodes matching test["name"] == test_case_steps[i]['step']['raw'] and test["state"], do that filtering when you grab the parent. Same for the XML, can you use XPath or similar to filter down to xml_testcase.attrib["name"] == test_case_steps[i]['step']['raw'] and "hook" not in xml_testcase.attrib["name"] before you start?

Once you have all that, the Jira-specific handling of errors (self.jira_obj.send_put) can be abstracted out to its own function that accepts the id, test step id and result object.