You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Tools/TestRailImporter/tests/unit/test_testrail_importer.py

286 lines
12 KiB
Python

"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Unit tests for ~/TestRailImporter/lib/testrail_importer/testrail_importer.py
"""
try: # py2
import mock
except ImportError: # py3
import unittest.mock as mock
try: # py2
import __builtin__
builtin_module = '__builtin__'
except ImportError: #py3
import builtins
builtin_module = 'builtins'
import argparse
import os
import pytest
import sys
import lib.testrail_importer.testrail_importer as testrail_importer
DEFAULT_ARGS = [
{'name': "--testrail-xml",
'nargs': '?',
'required': True,
'help': 'help text',
},
{'name': "--testrail-url",
'nargs': '?',
'required': True,
'help': 'help text',
},
{'name': "--testrail-user",
'nargs': '?',
'required': True,
'help': 'help text',
},
{'name': "--testrail-project-id",
'required': True,
'help': 'help text',
},
{'name': "--testrail-password",
'help': 'help text',
},
{'name': "--testrun-name",
'help': 'help text',
'default': 'Automated TestRail Report'
},
{'name': "--logs-folder",
'help': 'help text',
'default': 'reports'
},
{'name': "--testrun-id",
'help': 'help text'
},
{'name': "--testrail-suite-id",
'help': 'help text',
},
]
DEFAULT_LAUNCH_CMD = ['--testrail-xml', 'xml-path',
'--testrail-url', 'https://url-string.dummyurl',
'--testrail-user', 'user@email.email',
'--testrail-project-id', '1234567890']
def create_parser(arg_values):
parser = argparse.ArgumentParser(description="Mocked")
for value in arg_values:
parser.add_argument(value.get('name', None), nargs=value.get('nargs', None),
required=value.get('required', None), help=value.get('help', None),
default=value.get('default', None), )
return parser
class MockedTTY(object):
"""Python2 cannot mock sys.stdin.isatty(), so this proxy object is required."""
def __init__(self, underyling, tty_status):
self.__underlying = underyling
self.tty_status = tty_status
def __getattr__(self, name):
return getattr(self.__underlying, name)
def isatty(self):
return self.tty_status
@mock.patch('os.path.realpath', mock.MagicMock(return_value='dummy_realpath'))
@mock.patch('os.path.dirname', mock.MagicMock(return_value='dummy_dirname'))
@mock.patch("{}.open".format(builtin_module), mock.mock_open())
@pytest.mark.unit
class TestImporter:
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_Init_ValidArgParse_SetsCliArgs(self, mock_cli_args):
mock_parser = create_parser(DEFAULT_ARGS)
mock_args = mock_parser.parse_args(DEFAULT_LAUNCH_CMD)
mock_cli_args.return_value = mock_args
under_test = testrail_importer.TestRailImporter()
assert under_test._cli_args == mock_args
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_FilterTestCases_HasCaseIDs_ReturnsList(self, mock_cli_args):
mock_parser = create_parser(DEFAULT_ARGS)
mock_args = mock_parser.parse_args(DEFAULT_LAUNCH_CMD)
mock_cli_args.return_value = mock_args
testrun_results = [{'case_ids': [12345]}, {'case_ids': [11111]}]
under_test = testrail_importer.TestRailImporter()._TestRailImporter__filter_test_cases(
testrun_results)
assert under_test == [{'case_id': 12345, 'case_ids': [12345]},
{'case_id': 11111, 'case_ids': [11111]}]
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_FilterTestCaseIDs_HasCaseIDs_ReturnsListWithValues(self, mock_cli_args):
mock_parser = create_parser(DEFAULT_ARGS)
mock_args = mock_parser.parse_args(DEFAULT_LAUNCH_CMD)
mock_cli_args.return_value = mock_args
test_result = {'random_key_from_xml': 'test', 'case_ids': [12345, 11111]}
under_test = testrail_importer.TestRailImporter()._TestRailImporter__filter_test_case_ids(
test_result)
assert under_test == [
{'random_key_from_xml': 'test', 'case_id': 12345, 'case_ids': [12345, 11111]},
{'random_key_from_xml': 'test', 'case_id': 11111, 'case_ids': [12345, 11111]}
]
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_FilterTestCaseIDs_NoCaseIDs_ReturnsEmptyList(self, mock_cli_args):
mock_parser = create_parser(DEFAULT_ARGS)
mock_args = mock_parser.parse_args(DEFAULT_LAUNCH_CMD)
mock_cli_args.return_value = mock_args
test_result = {'random_key_from_xml': 'test', 'some_other_key': 'something'}
under_test = testrail_importer.TestRailImporter()._TestRailImporter__filter_test_case_ids(
test_result)
assert under_test == []
@mock.patch('lib.testrail_importer.testrail_importer.argparse.ArgumentParser')
def test_CliArgs_AllCLIArgs_ReturnsParsedArgs(self, mock_arg_parser):
expected_attribute_values = {
'testrail_xml': 'xml-path',
'testrail_url': 'https://url.url.asdf',
'testrail_user': 'user@email.email',
'testrail_project_id': '1234567890',
'testrail_password': 'always_censor_me',
'testrun_name': 'Test Run Name',
'logs_folder': 'dummy_name',
'testrun_id': '11111111111',
'testrail_suite_id': '1212121212',
}
mock_arg_parser.return_value = mock.MagicMock()
for mock_attribute in expected_attribute_values.keys():
mock_arg_parser.add_argument.side_effect = [
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute]),
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute]),
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute]),
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute]),
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute]),
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute]),
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute]),
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute]),
setattr(mock_arg_parser, mock_attribute, expected_attribute_values[mock_attribute])
]
testrail_importer.TestRailImporter() # cli_args() called in __init__()
for expected_attribute in expected_attribute_values.keys():
assert getattr(mock_arg_parser, expected_attribute) == expected_attribute_values[expected_attribute]
@mock.patch('lib.testrail_importer.testrail_tools.testrail_connection')
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_ProjectSuiteCheck_HasSuitesHasSuiteIDHasRunID_ReturnsTrue(self, mock_cli_args, mock_testrail_connection):
mock_testrail_connection.get_suites.return_value = [{u'id': 123}, {u'id': 456}]
mock_parser = create_parser(DEFAULT_ARGS)
new_launch_cmd = []
new_launch_cmd.extend(DEFAULT_LAUNCH_CMD)
new_launch_cmd.extend(['--testrail-suite-id', '123'])
mock_args = mock_parser.parse_args(new_launch_cmd)
mock_cli_args.return_value = mock_args
under_test = testrail_importer.TestRailImporter().project_suite_check(mock_testrail_connection, '1')
assert under_test is True
@mock.patch('lib.testrail_importer.testrail_tools.testrail_connection')
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_ProjectSuiteCheck_HasSuitesNoSuiteIDNoRunID_RaisesTestRailImporterError(self, mock_cli_args,
mock_testrail_connection):
mock_testrail_connection.get_suites.return_value = [{u'id': 123}, {u'id': 456}]
mock_parser = create_parser(DEFAULT_ARGS)
mock_args = mock_parser.parse_args(DEFAULT_LAUNCH_CMD)
mock_cli_args.return_value = mock_args
with pytest.raises(testrail_importer.TestRailImporterError):
testrail_importer.TestRailImporter().project_suite_check(mock_testrail_connection, '1')
@mock.patch('lib.testrail_importer.testrail_tools.testrail_connection')
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_ProjectSuiteCheck_HasSuitesNoSuiteIDHasRunID_ReturnsTrue(self, mock_cli_args, mock_testrail_connection):
mock_testrail_connection.get_suites.return_value = []
mock_parser = create_parser(DEFAULT_ARGS)
new_launch_cmd = []
new_launch_cmd.extend(DEFAULT_LAUNCH_CMD)
new_launch_cmd.extend(['--testrun-id', '123'])
mock_args = mock_parser.parse_args(new_launch_cmd)
mock_cli_args.return_value = mock_args
under_test = testrail_importer.TestRailImporter().project_suite_check(mock_testrail_connection, '1')
assert under_test is True
@mock.patch('os.path.isdir')
@mock.patch('lib.testrail_importer.testrail_importer.logging')
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_StartLog_HasLogDirectory_SetsLogging(self, mock_cli_args, mock_logging, mock_isdir):
mock_parser = create_parser(DEFAULT_ARGS)
mock_args = mock_parser.parse_args(DEFAULT_LAUNCH_CMD)
mock_cli_args.return_value = mock_args
logs_folder = 'dummy_logs_folder'
mock_isdir.return_value = True
testrail_importer.TestRailImporter().start_log(logs_folder)
assert mock_logging.Formatter.call_count == 2
mock_logging.FileHandler.assert_called_once()
mock_logging.StreamHandler.assert_called_once()
@mock.patch('lib.testrail_importer.testrail_importer.logging', mock.MagicMock())
@mock.patch('os.makedirs')
@mock.patch('os.path.isdir')
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_StartLog_NoLogDirectory_CreatesLogDirectorySetsLogging(self, mock_cli_args, mock_isdir, mock_makedirs):
mock_parser = create_parser(DEFAULT_ARGS)
mock_args = mock_parser.parse_args(DEFAULT_LAUNCH_CMD)
mock_cli_args.return_value = mock_args
logs_folder = 'dummy_logs_folder'
mock_isdir.return_value = False
testrail_importer.TestRailImporter().start_log(logs_folder)
mock_makedirs.assert_called_with(
os.path.join(
'dummy_dirname',
'..',
'..',
'dummy_logs_folder'))
@mock.patch(
'lib.testrail_importer.testrail_tools.testrail_report_converter.TestRailReportConverter', mock.MagicMock())
@mock.patch('getpass.getpass', mock.MagicMock(return_value='password'))
@mock.patch('lib.testrail_importer.testrail_tools.testrail_connection.TestRailConnection')
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.project_suite_check')
@mock.patch('lib.testrail_importer.testrail_importer.TestRailImporter.cli_args')
def test_Main_HasTTYNoID_PostsTestResults(self, mock_cli_args, mock_suite_check, mock_testrail_connection):
sys.stdin = MockedTTY(sys.stdin, True)
mock_parser = create_parser(DEFAULT_ARGS)
mock_args = mock_parser.parse_args(DEFAULT_LAUNCH_CMD)
mock_cli_args.return_value = mock_args
testrail_importer.TestRailImporter().main()
mock_testrail_connection.assert_called_with(password='password',
url='https://url-string.dummyurl',
user='user@email.email')
mock_suite_check.assert_called_once()
sys.stdin = sys.stdin