def main(zigzag_config_file, junit_input_file, pprint_on_fail): """Upload JUnitXML results to qTest manager. \b Required Arguments: ZIGZAG_CONFIG_FILE A valid json config file for zigzag. JUNIT_INPUT_FILE A valid JUnit XML results file. \b Required Environment Variables: QTEST_API_TOKEN The qTest API token to use for authorization """ api_token_env_var = 'QTEST_API_TOKEN' try: if not os.environ.get(api_token_env_var): raise RuntimeError( 'The "{}" environment variable is not defined! ' 'See help for more details.'.format(api_token_env_var)) zz = ZigZag(junit_input_file, zigzag_config_file, os.environ[api_token_env_var], pprint_on_fail) zz.parse() job_id = zz.upload_test_results() click.echo(click.style("\nQueue Job ID: {}".format(str(job_id)))) click.echo(click.style("\nSuccess!", fg='green')) except (RuntimeError, ZigZagError) as e: click.echo(click.style(str(e), fg='red')) click.echo(click.style("\nFailed!", fg='red')) sys.exit(1)
def pytest_sessionfinish(session): """This hook is used by pytest to build the junit XML Using ZigZag as a library we upload in the pytest runtime Args: session (_pytest.main.Session): The pytest session object """ SESSION_MESSAGES.drain( ) # need to reset this on every pass through this hook if session.config.pluginmanager.hasplugin('junitxml'): zz_option = _get_option_of_highest_precedence(session.config, 'zigzag') pytest_zigzag_config = _get_option_of_highest_precedence( session.config, 'pytest-zigzag-config') if zz_option and pytest_zigzag_config: try: junit_file_path = getattr(session.config, '_xml', None).logfile # noinspection PyTypeChecker # validate token token = _validate_qtest_token(os.environ['QTEST_API_TOKEN']) zz = ZigZag(junit_file_path, pytest_zigzag_config, token) job_id = zz.upload_test_results() SESSION_MESSAGES.append("ZigZag upload was successful!") SESSION_MESSAGES.append("Queue Job ID: {}".format(job_id)) except Exception as e: # we want this super broad so we dont break test execution SESSION_MESSAGES.append('The ZigZag upload was not successful') SESSION_MESSAGES.append("Original error message:\n\n{}".format( str(e)))
def test_schema_violation_with_pprint_on_fail(self, missing_test_id_xml, mocker): """Verify that JUnitXML that violates the schema with 'pprint_on_fail' enabled with emit an error message with the XML pretty printed in the error message.""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) # Expectations error_msg_exp = '---DEBUG XML PRETTY PRINT---' # Test try: zz = ZigZag(missing_test_id_xml, TOKEN, PROJECT_ID, TEST_CYCLE, pprint_on_fail=True) zz.parse() except RuntimeError as e: assert error_msg_exp in str(e)
def invoke_zigzag(self, force_clean_up=True): """Execute the ZigZag CLI. Args: force_clean_up (bool): Flag indicating whether previous test data should be cleaned up first before execution. (Default: True) """ if force_clean_up: self.clean_up() self.tests.reset( ) # This is for super safety in case a developer was being tricky with execution with open(self._junit_xml_file_path, 'w') as f: f.write( self._junit_template.render(tests=self._tests, global_props=self._global_props)) zz = ZigZag(self._junit_xml_file_path, self._qtest_api_token, self._qtest_project_id, self._qtest_root_test_cycle.name, False) zz.parse() self._last_invocation_queue_job_id = zz.upload_test_results()
def test_invalid_classname(self, invalid_classname_xml, mocker): """Verify that JUnitXML that has an invalid 'classname' attribute for a testcase raises a RuntimeError.""" object_id = 12345 # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = object_id mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': object_id }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(invalid_classname_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse() # Test with pytest.raises(RuntimeError): # noinspection PyStatementEffect zz.test_logs[0].qtest_test_log
def test_link_test_case_not_created_yet(self, single_passing_xml, mocker): """The happy path""" response_body = { "links": [], "page": 1, "page_size": 1, "total": 0, "items": [] } # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.SearchApi.search', return_value=response_body) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts') mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response_body) mocker.patch('requests.post', return_value=mock_post_response) # Setup zz = ZigZag(single_passing_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse() rlf = RequirementsLinkFacade(zz) log = zz.test_logs[0] # Test rlf.link() # After think link we should have much more information about linked resource assert ['ASC-123', 'ASC-456'] == log.jira_issues assert [] == log.qtest_requirements assert log.qtest_testcase_id is None
def test_happy_path(self, single_passing_xml, mocker): """Verify that the function can upload results from a JUnitXML file that contains a single passing test""" # Expectation job_id = '54321' # Mock test_cycle_name = 'queens' test_cycle_pid = 'CL-1' mock_get_tc_resp = mocker.Mock(spec=swagger_client.TestCycleResource) mock_create_tc_resp = mocker.Mock( spec=swagger_client.TestCycleResource) mock_get_tc_resp.to_dict.return_value = { 'name': 'queens', 'pid': 'CL-2' } mock_create_tc_resp.to_dict.return_value = { 'name': test_cycle_name, 'pid': test_cycle_pid } mock_queue_resp = mocker.Mock(state='IN_WAITING', id=job_id) mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.TestlogApi.submit_automation_test_logs_0', return_value=mock_queue_resp) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) mocker.patch('swagger_client.TestcycleApi.get_test_cycles', return_value=[mock_get_tc_resp]) mocker.patch('swagger_client.TestcycleApi.create_cycle', return_value=mock_create_tc_resp) # Setup zz = ZigZag(single_passing_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse() # Test response = zz.upload_test_results() assert int(job_id) == response
def test_classname_containing_dashes(self, classname_with_dashes_xml, mocker): """Verify that JUnitXML that has a 'classname' containing dashes (captured from the py.test filename) is validated correctly. """ object_id = 12345 # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = object_id mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': object_id }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(classname_with_dashes_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse() # noinspection PyUnresolvedReferences test_log_dict = zz.test_logs[0].qtest_test_log.to_dict() # Expectation test_name = 'test_verify_kibana_horizon_access_with_no_ssh' module_names = [ 'r16.2.0', 'PM_rpc-openstack-pike-rc-xenial_mnaio_no_artifacts-swift-system', 'molecule-validate-neutron-deploy', 'default', 'test_for_acs-150', 'TestForRPC10PlusPostDeploymentQCProcess' ] test_log_exp = pytest.helpers.merge_dicts(SHARED_TEST_LOG_EXP, { 'name': test_name, 'status': 'PASSED', 'module_names': module_names }) # Test for exp in test_log_exp: assert test_log_exp[exp] == test_log_dict[exp]
def test_invalid_file_path(self, mocker): """Verify that an invalid file path raises an exception""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) # Test with pytest.raises(RuntimeError): zz = ZigZag('/path/does/not/exist', TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse()
def test_missing_junit_xml_root(self, bad_junit_root, mocker): """Verify that XML files missing the expected JUnitXML root element raises an exception""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) # Test with pytest.raises(RuntimeError): zz = ZigZag(bad_junit_root, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse()
def test_missing_test_id_xml(self, missing_test_id_xml, mocker): """Verify that JUnitXML that is missing the 'test_id' test case property causes a RuntimeError.""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) # Test with pytest.raises(RuntimeError): zz = ZigZag(missing_test_id_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse()
def test_invalid_xml_content(self, bad_xml, mocker): """Verify that invalid XML file content raises an exception""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) # Test with pytest.raises(RuntimeError): zz = ZigZag(bad_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse()
def test_missing_build_url_xml(self, missing_build_url_xml, simple_json_config, mocker): """Verify that JUnitXML that is missing the test suite 'BUILD_URL' property element causes a RuntimeError.""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) # Test with pytest.raises(RuntimeError): zz = ZigZag(missing_build_url_xml, simple_json_config, TOKEN) zz.parse()
def test_failure_to_get_test_cycles(self, single_passing_xml, mocker): """Verify that API failure when retrieving test cycles is caught.""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.TestcycleApi.get_test_cycles', side_effect=ApiException('Super duper failure!')) # Setup test_cycle_name = 'TestCycle1' zz = ZigZag(single_passing_xml, TOKEN, PROJECT_ID, TEST_CYCLE) mhf = ModuleHierarchyFacade(zz) # Test with pytest.raises(RuntimeError): mhf.discover_root_test_cycle(test_cycle_name)
def test_junit_xml_attachment(self, single_passing_xml, simple_json_config, mocker): """Verify that an xml file is attached to the qTest testlog """ object_id = 12345 # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = object_id mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': object_id }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(single_passing_xml, simple_json_config, TOKEN) zz.parse() # noinspection PyUnresolvedReferences test_log_dict = zz.test_logs[0].qtest_test_log.to_dict() # Expectation attachment_exp_name_regex = re.compile(r'^junit_.+\.xml$') attachment_exp_content_type = 'application/xml' attachment_exp_data_md5 = 'f3b2303ccf8a76a9e20d2099e9b2f29c' # Test assert attachment_exp_name_regex.match( test_log_dict['attachments'][0]['name']) is not None assert attachment_exp_content_type == test_log_dict['attachments'][0][ 'content_type'] assert attachment_exp_data_md5 == md5( test_log_dict['attachments'][0]['data'].encode( 'UTF-8')).hexdigest()
def test_exceeds_max_file_size(self, flat_all_passing_xml, mocker): """Verify that XML files that exceed the max file size are rejected""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' file_size = 52428801 mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('os.path.getsize', return_value=file_size) # Test with pytest.raises(RuntimeError): zz = ZigZag(flat_all_passing_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse()
def test_error(self, single_error_xml, mocker): """Verify that a JUnitXML error test will parse into a single TestLog. """ object_id = 12345 # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = object_id mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': object_id }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(single_error_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse() # noinspection PyUnresolvedReferences test_log = zz.test_logs[0] assert 'test_error' == test_log.name assert 'FAILED' == test_log.status assert 'def error_fixture(host):' in test_log.failure_output \ or 'log truncated. Please see attached log file.' in test_log.failure_output assert '2018-04-10T21:38:18Z' == test_log.start_date assert '2018-04-10T21:38:19Z' == test_log.end_date assert ['ASC-123', 'ASC-456'] == test_log.jira_issues assert '1' == test_log.automation_content assert [object_id, object_id] == test_log.qtest_requirements assert object_id == test_log.qtest_testcase_id
def test_pass(self, single_passing_xml, mocker): """Verify that a valid qTest 'AutomationTestLogResource' swagger model is generated from a JUnitXML file that contains a single passing test. """ object_id = 12345 # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = object_id mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': object_id }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(single_passing_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse() # noinspection PyUnresolvedReferences test_log = zz.test_logs[0] assert 'test_pass' == test_log.name assert 'PASSED' == test_log.status assert '' == test_log.failure_output assert '2018-04-10T21:38:18Z' == test_log.start_date assert '2018-04-10T21:38:19Z' == test_log.end_date assert ['ASC-123', 'ASC-456'] == test_log.jira_issues assert '1' == test_log.automation_content assert [object_id, object_id] == test_log.qtest_requirements assert object_id == test_log.qtest_testcase_id # We look this up on instantiation of a TestLog
def test_load_file_happy_path(self, flat_all_passing_xml, simple_json_config, mocker): """Verify that a valid JUnitXML file can be loaded""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(flat_all_passing_xml, simple_json_config, TOKEN) zz.parse() # Expectations root_tag_atribute_exp = { 'errors': '0', 'failures': '0', 'name': 'pytest', 'skips': '0', 'tests': '5', 'time': '1.664' } # Test # noinspection PyProtectedMember assert root_tag_atribute_exp == zz._junit_xml.attrib
def test_job_queue_failure(self, single_passing_xml, mocker): """Verify that the function fails gracefully if the job queue reports a failure""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(single_passing_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse() # Test with pytest.raises(RuntimeError): zz.upload_test_results()
def test_api_exception(self, single_passing_xml, simple_json_config, mocker): """Verify that the function fails gracefully if the API endpoint reports an API exception""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.TestlogApi.submit_automation_test_logs_0', side_effect=ApiException('Super duper failure!')) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(single_passing_xml, simple_json_config, TOKEN) zz.parse() # Test with pytest.raises(RuntimeError): zz.upload_test_results()
def test_link(self, single_passing_xml, asc_zigzag_config_file, mocker): """The happy path""" id = 8675309 response_body = { "links": [], "page": 1, "page_size": 100, "total": 1, "items": [{ "id": id, "name": 'This is the name' }] } # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.SearchApi.search', return_value=response_body) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts') mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response_body) mocker.patch('requests.post', return_value=mock_post_response) # Setup zz = ZigZag(single_passing_xml, asc_zigzag_config_file, TOKEN) zz.parse() rlf = RequirementsLinkFacade(zz) log = zz.test_logs[0] # Test rlf.link() # After think link we should have much more information about linked resource assert ['ASC-123', 'ASC-456'] == log.jira_issues assert [id, id] == log.qtest_requirements assert id == log.qtest_testcase_id
def main(junit_input_file, qtest_project_id, qtest_test_cycle, pprint_on_fail, test_runner): """Upload JUnitXML results to qTest manager. \b Required Arguments: JUNIT_INPUT_FILE A valid JUnit XML results file. QTEST_PROJECT_ID The the target qTest Project ID for results \b Required Environment Variables: QTEST_API_TOKEN The qTest API token to use for authorization """ api_token_env_var = 'QTEST_API_TOKEN' try: if not os.environ.get(api_token_env_var): raise RuntimeError( 'The "{}" environment variable is not defined! ' 'See help for more details.'.format(api_token_env_var)) zz = ZigZag(junit_input_file, os.environ[api_token_env_var], qtest_project_id, qtest_test_cycle, pprint_on_fail) zz.test_runner = test_runner zz.parse() job_id = zz.upload_test_results() click.echo(click.style("\nQueue Job ID: {}".format(str(job_id)))) click.echo(click.style("\nSuccess!", fg='green')) except RuntimeError as e: click.echo(click.style(str(e), fg='red')) click.echo(click.style("\nFailed!", fg='red')) sys.exit(1)
def test_suite_with_tests(self, suite_all_passing_xml, simple_json_config, mocker): """Verify that a JUnitXML test suite will parse into multiple TestLogs. """ object_id = 12345 # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = object_id mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': object_id }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(suite_all_passing_xml, simple_json_config, TOKEN) zz.parse() # noinspection PyUnresolvedReferences test_logs = zz.test_logs # Test for log in test_logs: assert 'PASSED' == log.status assert re.match(r'test_pass\d', log.name)
def test_data_stored_on_mediator(self, asc_zigzag_config_file, flat_all_passing_xml, mocker): """verify that the ZigZag object stores properties after initialization""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 2983472 mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) # Setup zz = ZigZag(flat_all_passing_xml, asc_zigzag_config_file, TOKEN) zz.parse() # Test assert "12345" == zz.config_dict.get_config('project_id') assert len(zz.test_logs) assert 'https://rpc.jenkins.cit.rackspace.net/job/PM_rpc-openstack-pike-rc-xenial_mnaio_no_artifacts-swift-system/78/' == zz.build_url # noqa assert zz.junit_xml is not None assert '78' == zz.build_number assert False is zz.pprint_on_fail assert zz.testsuite_props
def test_create_test_cycle(self, single_passing_xml, mocker): """Verify that a new test cycle will be created when the desired cycle name cannot be found.""" # Setup test_cycle_name = 'Buttons' # Expectation test_cycle_pid_exp = 'CL-3' # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mock_get_tc_resp = mocker.Mock(spec=swagger_client.TestCycleResource) mock_create_tc_resp = mocker.Mock( spec=swagger_client.TestCycleResource) mock_get_tc_resp.to_dict.return_value = { 'name': 'queens', 'pid': 'CL-2' } mock_create_tc_resp.to_dict.return_value = { 'name': test_cycle_name, 'pid': test_cycle_pid_exp } response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.TestcycleApi.get_test_cycles', return_value=[mock_get_tc_resp]) mocker.patch('swagger_client.TestcycleApi.create_cycle', return_value=mock_create_tc_resp) # Setup zz = ZigZag(single_passing_xml, TOKEN, PROJECT_ID, TEST_CYCLE) mhf = ModuleHierarchyFacade(zz) # Test assert test_cycle_pid_exp == mhf.discover_root_test_cycle( test_cycle_name)
def test_label_not_found(self, single_fail_xml, mocker): """Search for a label that does not exist""" # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'foo' mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) response = {'items': [{'name': 'insert name here', 'id': 12345}], 'total': 1} mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) # Setup zz = ZigZag(single_fail_xml, TOKEN, PROJECT_ID, TEST_CYCLE) uf = UtilityFacade(zz) result = uf.find_custom_field_id_by_label('Failure Output', 'test-runs') assert result is None
def test_discover_existing_test_cycle_with_case_change( self, single_passing_xml, mocker): """Verify that the PID for an existing test cycle can be discovered when using a different case for search.""" # Expectation test_cycle_pid_exp = 'CL-2' # Mock mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' mock_tc_resp = mocker.Mock(spec=swagger_client.TestCycleResource) mock_tc_resp.to_dict.return_value = { 'name': 'queens', 'pid': test_cycle_pid_exp } response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.TestcycleApi.get_test_cycles', return_value=[mock_tc_resp]) # Setup test_cycle_name = 'Queens' zz = ZigZag(single_passing_xml, TOKEN, PROJECT_ID, TEST_CYCLE) mhf = ModuleHierarchyFacade(zz) # Test assert test_cycle_pid_exp == mhf.discover_root_test_cycle( test_cycle_name)
def test_mix_status(self, flat_mix_status_xml, mocker): """Verify that a valid qTest 'AutomationRequest' swagger model is generated from a JUnitXML file that contains multiple tests with different status results """ # Mock test_cycle_name = 'queens' test_cycle_pid = 'CL-1' mock_get_tc_resp = mocker.Mock(spec=swagger_client.TestCycleResource) mock_create_tc_resp = mocker.Mock( spec=swagger_client.TestCycleResource) mock_get_tc_resp.to_dict.return_value = { 'name': 'queens', 'pid': 'CL-2' } mock_create_tc_resp.to_dict.return_value = { 'name': test_cycle_name, 'pid': test_cycle_pid } mock_field_resp = mocker.Mock(spec=swagger_client.FieldResource) mock_field_resp.id = 12345 mock_field_resp.label = 'Failure Output' response = { 'items': [{ 'name': 'insert name here', 'id': 12345 }], 'total': 1 } mock_link_response = mocker.Mock( spec=swagger_client.LinkedArtifactContainer) mock_post_response = mocker.Mock(spec=requests.Response) mock_post_response.text = json.dumps(response) mocker.patch('requests.post', return_value=mock_post_response) mocker.patch('swagger_client.FieldApi.get_fields', return_value=[mock_field_resp]) mocker.patch('swagger_client.ObjectlinkApi.link_artifacts', return_value=[mock_link_response]) mocker.patch('swagger_client.TestcycleApi.get_test_cycles', return_value=[mock_get_tc_resp]) mocker.patch('swagger_client.TestcycleApi.create_cycle', return_value=mock_create_tc_resp) # Setup zz = ZigZag(flat_mix_status_xml, TOKEN, PROJECT_ID, TEST_CYCLE) zz.parse() auto_req_dict = zz._generate_auto_request().to_dict() # Expectation test_logs_exp = [ pytest.helpers.merge_dicts(SHARED_TEST_LOG_EXP, { 'name': 'test_pass', 'status': 'PASSED' }), pytest.helpers.merge_dicts(SHARED_TEST_LOG_EXP, { 'name': 'test_fail', 'status': 'FAILED' }), pytest.helpers.merge_dicts(SHARED_TEST_LOG_EXP, { 'name': 'test_error', 'status': 'FAILED' }), pytest.helpers.merge_dicts(SHARED_TEST_LOG_EXP, { 'name': 'test_skip', 'status': 'SKIPPED' }) ] # Test for x in range(len(auto_req_dict['test_logs'])): for key in test_logs_exp[x]: expected = test_logs_exp[x][key] observed = auto_req_dict['test_logs'][x][key] assert expected == observed