From 3fdb7a41325a8946ca75b40ccefd01067acb589b Mon Sep 17 00:00:00 2001 From: Reverb C Date: Mon, 11 Feb 2019 00:57:42 -0800 Subject: [PATCH] batch upload test results (#85) * use batch upload API to upload test results * fix unit test to adapt internal api change --- pytest_testrail/plugin.py | 35 +++++++++++++++-------------- tests/test_plugin.py | 47 +++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/pytest_testrail/plugin.py b/pytest_testrail/plugin.py index 3239fa8..7c01733 100644 --- a/pytest_testrail/plugin.py +++ b/pytest_testrail/plugin.py @@ -25,7 +25,7 @@ TESTRAIL_PREFIX = 'testrail' -ADD_RESULT_URL = 'add_result_for_case/{}/{}' +ADD_RESULTS_URL = 'add_results_for_cases/{}' ADD_TESTRUN_URL = 'add_run/{}' CLOSE_TESTRUN_URL = 'close_run/{}' CLOSE_TESTPLAN_URL = 'close_plan/{}' @@ -268,30 +268,31 @@ def add_results(self, testrun_id): print('[{}] Option "Include all testcases from test suite for test run" activated'.format(TESTRAIL_PREFIX)) # Publish results + data = {'results': []} for result in self.results: - data = {'status_id': result['status_id']} + entry = {'status_id': result['status_id'], 'case_id': result['case_id']} if self.version: - data['version'] = self.version + entry['version'] = self.version comment = result.get('comment', '') if comment: # Indent text to avoid string formatting by TestRail. Limit size of comment. - data['comment'] = u"# Pytest result: #\n" - data['comment'] += u'Log truncated\n...\n' if len(str(comment)) > COMMENT_SIZE_LIMIT else u'' - data['comment'] += u" " + converter(str(comment), "utf-8")[-COMMENT_SIZE_LIMIT:].replace('\n', '\n ') + entry['comment'] = u"# Pytest result: #\n" + entry['comment'] += u'Log truncated\n...\n' if len(str(comment)) > COMMENT_SIZE_LIMIT else u'' + entry['comment'] += u" " + converter(str(comment), "utf-8")[-COMMENT_SIZE_LIMIT:].replace('\n', '\n ') duration = result.get('duration') if duration: duration = 1 if (duration < 1) else int(round(duration)) # TestRail API doesn't manage milliseconds - data['elapsed'] = str(duration) + 's' - response = self.client.send_post( - ADD_RESULT_URL.format(testrun_id, result['case_id']), - data, - cert_check=self.cert_check - ) - error = self.client.get_error(response) - if error: - print('[{}] Info: Testcase #{} not published for following reason: "{}"'.format(TESTRAIL_PREFIX, - result['case_id'], - error)) + entry['elapsed'] = str(duration) + 's' + data['results'].append(entry) + + response = self.client.send_post( + ADD_RESULTS_URL.format(testrun_id), + data, + cert_check=self.cert_check + ) + error = self.client.get_error(response) + if error: + print('[{}] Info: Testcases not published for following reason: "{}"'.format(TESTRAIL_PREFIX, error)) def create_test_run( self, assign_user_id, project_id, suite_id, include_all, testrun_name, tr_keys): diff --git a/tests/test_plugin.py b/tests/test_plugin.py index a9d500d..65078f4 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -171,18 +171,14 @@ def test_pytest_sessionfinish(api_client, tr_plugin): tr_plugin.pytest_sessionfinish(None, 0) - expected_uri = plugin.ADD_RESULT_URL.format(tr_plugin.testrun_id, 1234) - expected_data = {'status_id': TESTRAIL_TEST_STATUS["passed"], 'version': '1.0.0.0', 'elapsed': '3s'} - api_client.send_post.call_args_list[0] == call(expected_uri, expected_data, cert_check=True) - - expected_uri = plugin.ADD_RESULT_URL.format(tr_plugin.testrun_id, 1234) - expected_data = {'status_id': TESTRAIL_TEST_STATUS["failed"], 'version': '1.0.0.0', 'elapsed': '3s'} - api_client.send_post.call_args_list[1] == call(expected_uri, expected_data, cert_check=True) + expected_data = {'results': [ + {'case_id': 1234, 'status_id': TESTRAIL_TEST_STATUS["passed"], 'version': '1.0.0.0', 'elapsed': '3s'}, + {'case_id': 1234, 'status_id': TESTRAIL_TEST_STATUS["failed"], 'version': '1.0.0.0', 'elapsed': '3s'}, + {'case_id': 5678, 'status_id': TESTRAIL_TEST_STATUS["blocked"], 'version': '1.0.0.0', 'elapsed': '1s', + 'comment': "# Pytest result: #\n An error"} + ]} - expected_uri = plugin.ADD_RESULT_URL.format(tr_plugin.testrun_id, 5678) - expected_data = {'status_id': TESTRAIL_TEST_STATUS["blocked"], 'version': '1.0.0.0', 'elapsed': '1s', - 'comment': "# Pytest result: #\n An error"} - api_client.send_post.call_args_list[2] == call(expected_uri, expected_data, cert_check=True) + api_client.send_post.assert_any_call(plugin.ADD_RESULTS_URL.format(tr_plugin.testrun_id), expected_data, cert_check=True) def test_pytest_sessionfinish_testplan(api_client, tr_plugin): @@ -195,20 +191,17 @@ def test_pytest_sessionfinish_testplan(api_client, tr_plugin): api_client.send_get.return_value = TESTPLAN tr_plugin.pytest_sessionfinish(None, 0) - expected_data_1234 = {'status_id': TESTRAIL_TEST_STATUS["passed"], 'version': '1.0.0.0', 'elapsed': '3s'} - expected_data_5678 = {'status_id': TESTRAIL_TEST_STATUS["blocked"], 'version': '1.0.0.0', 'elapsed': '1s', - 'comment': "# Pytest result: #\n An error"} - + expected_data = {'results': [ + {'case_id': 1234, 'status_id': TESTRAIL_TEST_STATUS["passed"], 'version': '1.0.0.0', 'elapsed': '3s'}, + {'case_id': 5678, 'status_id': TESTRAIL_TEST_STATUS["blocked"], 'version': '1.0.0.0', 'elapsed': '1s', + 'comment': "# Pytest result: #\n An error"} + ]} print(api_client.send_post.call_args_list) - api_client.send_post.assert_any_call(plugin.ADD_RESULT_URL.format(59, 1234), - expected_data_1234, cert_check=True) - api_client.send_post.assert_any_call(plugin.ADD_RESULT_URL.format(59, 5678), - expected_data_5678, cert_check=True) - api_client.send_post.assert_any_call(plugin.ADD_RESULT_URL.format(61, 1234), - expected_data_1234, cert_check=True) - api_client.send_post.assert_any_call(plugin.ADD_RESULT_URL.format(61, 5678), - expected_data_5678, cert_check=True) + api_client.send_post.assert_any_call(plugin.ADD_RESULTS_URL.format(59, 1234), + expected_data, cert_check=True) + api_client.send_post.assert_any_call(plugin.ADD_RESULTS_URL.format(61, 5678), + expected_data, cert_check=True) @pytest.mark.parametrize('include_all', [True, False]) @@ -276,7 +269,7 @@ def test_close_test_run(api_client, tr_plugin): tr_plugin.pytest_sessionfinish(None, 0) expected_uri = plugin.CLOSE_TESTRUN_URL.format(tr_plugin.testrun_id) - api_client.send_post.call_args_list[3] = call(expected_uri, {}, cert_check=True) + api_client.send_post.call_args_list[1] = call(expected_uri, {}, cert_check=True) def test_close_test_plan(api_client, tr_plugin): @@ -292,7 +285,7 @@ def test_close_test_plan(api_client, tr_plugin): tr_plugin.pytest_sessionfinish(None, 0) expected_uri = plugin.CLOSE_TESTPLAN_URL.format(tr_plugin.testplan_id) - api_client.send_post.call_args_list[3] = call(expected_uri, {}, cert_check=True) + api_client.send_post.call_args_list[1] = call(expected_uri, {}, cert_check=True) def test_dont_publish_blocked(api_client): @@ -317,8 +310,8 @@ def test_dont_publish_blocked(api_client): api_client.send_get.assert_called_once_with(plugin.GET_TESTS_URL.format(my_plugin.testrun_id), cert_check=True) - expected_uri = plugin.ADD_RESULT_URL.format(my_plugin.testrun_id, 1234) - expected_data = {'status_id': TESTRAIL_TEST_STATUS["blocked"], 'version': '1.0.0.0'} + expected_uri = plugin.ADD_RESULTS_URL.format(my_plugin.testrun_id) + expected_data = {'results': [{'case_id': 1234, 'status_id': TESTRAIL_TEST_STATUS["blocked"], 'version': '1.0.0.0'}]} len(api_client.send_post.call_args_list) == 1 api_client.send_post.call_args_list[0] == call(expected_uri, expected_data, cert_check=True)