Merge pull request #56 feature-NEWDWH2021-644-controller into develop-6crm

This commit is contained in:
下田雅人 2022-08-16 15:04:20 +09:00
commit bb3a4c22ba
7 changed files with 962 additions and 22 deletions

View File

@ -74,7 +74,7 @@
```text
.
├── Dockerfile -- Dokcerイメージを作成するためのファイル
├── Dockerfile -- Dockerイメージを作成するためのファイル
├── Pipfile -- Pipenv(Pythonの仮想環境管理モジュール)で、依存関係を管理するためのファイル
├── Pipfile.lock -- Pipenvでインストールされた依存関係のバージョン固定ファイル
├── README.md -- README
@ -105,7 +105,8 @@
│ └── logger.py -- ログ管理クラス
└── tests/ -- テストコード置き場
├── aws -- AWS操作モジュールのテスト
├── test_utils/ -- テストコードで共通的に使用できる関数群
├── aws/ -- AWS操作モジュールのテスト
├── ... -- src配下のモジュール構成と同じ階層にテストコードを追加していく
├── conftest.py -- pytestのフィクスチャやフックを管理するファイル
└── docstring_parser.py -- pytest-htmlのレポート出力用のヘルパー

View File

@ -2,4 +2,7 @@ from src.controller import controller
"""CRMデータ取得処理のエントリーポイント"""
if __name__ == '__main__':
controller()
try:
exit(controller())
except Exception:
exit(0)

View File

@ -22,7 +22,7 @@ class FetchTargetObjects():
def __init__(self, object_info_file_dict) -> None:
self.__objects = object_info_file_dict
self.__dict_checker = DictChecker(self.__objects)
self.validate()
self.__validate()
self.__i = 0
def __iter__(self):
@ -35,7 +35,7 @@ class FetchTargetObjects():
self.__i += 1
return value
def validate(self) -> None:
def __validate(self) -> None:
self.__dict_checker.assert_key_exist(OBJECTS_KEY)
self.__dict_checker.assert_data_type(OBJECTS_KEY, OBJECTS_TYPE)

View File

@ -33,37 +33,40 @@ def controller() -> None:
# ③ object_infoのobjectsキーの値の件数分ループする
logger.info('I-CTRL-03 取得対象オブジェクトのループ処理開始')
process_result = fetch_crm_data(fetch_target_objects, execute_datetime, process_result)
process_result = _fetch_crm_data(fetch_target_objects, execute_datetime, process_result)
# ④ すべてのオブジェクトの処理が完了したことと、オブジェクト毎の処理結果をログに出力する
logger.info(f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{process_result}]')
# 最終結果が0件(1件も処理されていない)の場合、ログ出力して処理を終了する
if len(process_result.keys()) == 0:
logger.info('I-CTRL-21 処理対象のデータが存在しませんでした')
return 0
# ⑤ 取得処理実施結果アップロード処理を呼び出す
logger.info('I-CTRL-18 CRM_取得処理実施結果ファイルアップロード処理開始')
upload_result_data_process(process_result, execute_datetime)
# ⑥ 最終結果をチェックし、チェック結果をログに出力
if not all([v == 'success' for v in process_result.values()]):
logger.error('E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください')
else:
logger.info('I-CTRL-19 すべてのデータの取得に成功しました')
_check_process_result(process_result)
# ⑦ CRMデータ取得処理終了ログを出力する
logger.info('I-CTRL-20 CRMデータ取得処理を終了します')
return exit(0)
return 0
except MeDaCaCRMDataFetchException as e:
logger.error(f'E-ERR-01 [{e.func_name}]でエラーが発生したため、処理を終了します')
logger.exception(f'{e.error_id} {e}')
return exit(0)
raise e
except Exception as e:
logger.exception('E-ERR-02 予期せぬエラーが発生したため、処理を終了します', e)
return exit(0)
logger.exception(f'E-ERR-02 予期せぬエラーが発生したため、処理を終了します エラー内容: [{e}]')
raise e
finally:
# ⑦ CRMデータ取得処理終了ログを出力する
logger.info('I-CTRL-20 CRMデータ取得処理を終了します')
def fetch_crm_data(fetch_target_objects: FetchTargetObjects, execute_datetime: ExecuteDateTime, process_result: dict):
def _fetch_crm_data(fetch_target_objects: FetchTargetObjects, execute_datetime: ExecuteDateTime, process_result: dict):
"""取得対象オブジェクト情報をループし、1オブジェクトごとのデータを取得する
Args:
@ -79,7 +82,7 @@ def fetch_crm_data(fetch_target_objects: FetchTargetObjects, execute_datetime: E
try:
process_result[object_info.get(OBJECT_NAME_KEY)] = 'fail'
fetch_crm_data_per_object(object_info, execute_datetime)
_fetch_crm_data_per_object(object_info, execute_datetime)
process_result[object_info.get(OBJECT_NAME_KEY)] = 'success'
@ -91,13 +94,13 @@ def fetch_crm_data(fetch_target_objects: FetchTargetObjects, execute_datetime: E
except Exception as e:
logger.info(
f'I-ERR-04 [{object_info.get(OBJECT_NAME_KEY)}] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します', e, exc_info=True)
f'I-ERR-04 [{object_info.get(OBJECT_NAME_KEY)}] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [{e}]', exc_info=True)
continue
return process_result
def fetch_crm_data_per_object(object_info: dict, execute_datetime: ExecuteDateTime) -> None:
def _fetch_crm_data_per_object(object_info: dict, execute_datetime: ExecuteDateTime) -> None:
"""オブジェクトごとにCRMのデータを取得し、取込フォルダにアップロードする
Args:
@ -136,6 +139,12 @@ def fetch_crm_data_per_object(object_info: dict, execute_datetime: ExecuteDateTi
crm_data_response = fetch_crm_data_process(target_object, last_fetch_datetime)
# 取得件数が0件の場合、次のオブジェクトの処理に移行する
if len(crm_data_response) == 0:
logger.info(
f'I-CTRL-22 [{target_object_name}]のレコード件数が0件のため、ファイルアップロードをスキップします')
return
# 7. 出力ファイル名をログ出力する
logger.info(
f'I-CTRL-10 [{target_object_name}] の出力ファイル名は [{target_object.upload_file_name}] となります')
@ -174,3 +183,18 @@ def fetch_crm_data_per_object(object_info: dict, execute_datetime: ExecuteDateTi
logger.info(f'I-CTRL-16 [{target_object_name}] 処理正常終了')
return
def _check_process_result(process_result: dict) -> None:
"""取得処理結果がすべて成功か、一部失敗しているかを判定し、ログ出力する
Args:
process_result (dict): 取得処理結果辞書オブジェクト
"""
if not all([v == 'success' for v in process_result.values()]):
logger.error('E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください')
return
logger.info('I-CTRL-19 すべてのデータの取得に成功しました')
return

View File

@ -79,4 +79,4 @@ def prepare_data_fetch_process():
logger.info('I-PRE-09 データ取得準備処理を終了します')
# ⑧ 次の処理へ移行する
return(fetch_target_objects, execute_datetime, process_result)
return (fetch_target_objects, execute_datetime, process_result)

View File

@ -0,0 +1,905 @@
import logging
from copy import deepcopy
from unittest.mock import MagicMock, patch
import pytest
from src import controller
from src.config.objects import (FetchTargetObjects, LastFetchDatetime,
TargetObject)
from src.error.exceptions import MeDaCaCRMDataFetchException
from src.system_var.constants import (CHK_JP_NAME, CONV_JP_NAME, CSVBK_JP_NAME,
DATE_JP_NAME, END_JP_NAME, FETCH_JP_NAME,
PRE_JP_NAME, RESBK_JP_NAME, UPD_JP_NAME,
UPLD_JP_NAME)
from src.util.execute_datetime import ExecuteDateTime
from .test_utils.log_message import generate_log_message_tuple
COMMON_OBJECT_INFOS = {
'objects': [
{
'object_name': 'Account',
'columns': [],
'upload_file_name': 'Account_YYYYMMDDHHMMSS'
},
{
'object_name': 'Contact',
'columns': [],
'upload_file_name': 'Contact_YYYYMMDDHHMMSS'
},
{
'object_name': 'Call2_vod__c',
'columns': [],
'upload_file_name': 'Call2_vod__c_YYYYMMDDHHMMSS'
}
]
}
COMMON_EXECUTE_DATETIME = ExecuteDateTime()
COMMON_FETCH_TARGET_OBJECTS = FetchTargetObjects(COMMON_OBJECT_INFOS)
COMMON_TARGET_OBJECTS_1 = TargetObject(COMMON_OBJECT_INFOS['objects'][0], COMMON_EXECUTE_DATETIME)
COMMON_TARGET_OBJECTS_2 = TargetObject(COMMON_OBJECT_INFOS['objects'][1], COMMON_EXECUTE_DATETIME)
COMMON_TARGET_OBJECTS_3 = TargetObject(COMMON_OBJECT_INFOS['objects'][2], COMMON_EXECUTE_DATETIME)
COMMON_LAST_FETCH_DATETIME = LastFetchDatetime({
'last_fetch_datetime_from': '1900-01-01T00:00:00.000Z',
'last_fetch_datetime_to': ''
}, COMMON_EXECUTE_DATETIME)
class ForTestMeDaCaCRMDataFetchException(MeDaCaCRMDataFetchException):
def __init__(self, error_id: str, func_name: str, message: str) -> None:
super().__init__(error_id, func_name, message)
class ForTestException(Exception):
# カスタム例外とインタフェースを合わせるための引数
def __init__(self, error_id: str, func_name: str, message: str) -> None:
super().__init__(message)
class TestController:
@pytest.fixture(autouse=True)
def setup_teardown(self):
# setup
self.mock_prepare_data_fetch_process = MagicMock()
self.mock_check_object_info_process = MagicMock()
self.mock_set_datetime_period_process = MagicMock()
self.mock_fetch_crm_data_process = MagicMock()
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
# run test
yield
# teardown
self.mock_prepare_data_fetch_process.reset_mock()
self.mock_check_object_info_process.reset_mock()
self.mock_set_datetime_period_process.reset_mock()
self.mock_fetch_crm_data_process.reset_mock()
self.mock_backup_crm_data_process.reset_mock()
self.mock_convert_crm_csv_data_process.reset_mock()
self.mock_backup_crm_csv_data_process.reset_mock()
self.mock_copy_crm_csv_data_process.reset_mock()
self.mock_upload_last_fetch_datetime_process.reset_mock()
self.mock_upload_result_data_process.reset_mock()
@pytest.fixture()
def run_control_process(self):
def _func():
with patch('src.controller.prepare_data_fetch_process', self.mock_prepare_data_fetch_process),\
patch('src.controller.check_object_info_process', self.mock_check_object_info_process),\
patch('src.controller.set_datetime_period_process', self.mock_set_datetime_period_process),\
patch('src.controller.fetch_crm_data_process', self.mock_fetch_crm_data_process),\
patch('src.controller.backup_crm_data_process', self.mock_backup_crm_data_process),\
patch('src.controller.convert_crm_csv_data_process', self.mock_convert_crm_csv_data_process),\
patch('src.controller.backup_crm_csv_data_process', self.mock_backup_crm_csv_data_process),\
patch('src.controller.copy_crm_csv_data_process', self.mock_copy_crm_csv_data_process),\
patch('src.controller.upload_last_fetch_datetime_process', self.mock_upload_last_fetch_datetime_process),\
patch('src.controller.upload_result_data_process', self.mock_upload_result_data_process):
controller.controller()
yield _func
@pytest.fixture()
def call_all_processes(self, caplog, run_control_process):
"""
コントロール処理内ですべてのプロセス関数が呼ばれることのテストで使用するフィクスチャ
各種プロセス関数をモック化し正常終了させるように動く
Yields:
dict: プロセス関数呼び出し後のモックの辞書
"""
def _func():
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(return_value=[{'Name': 'Test'}])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
yield _func
def test_call_all_processes(self, call_all_processes):
"""
Cases:
コントロール処理からすべてのプロセスが呼ばれること
Arranges:
- call_all_processesフィクスチャでコントロール処理を実行しておく
Expects:
- データ取得準備処理が1回のみ実行される
- オブジェクト情報形式チェック処理が複数回実行される
- データ取得期間設定処理が複数回実行される
- CRMデータ取得処理が複数回実行される
- CRM電文データバックアップ処理が複数回実行される
- CSV変換処理が複数回実行される
- CSVバックアップ処理が複数回実行される
- CSVアップロード処理が複数回実行される
- 前回取得日時ファイル更新処理が複数回実行される
- 取得処理実施結果アップロード処理が1回のみ実行される
"""
call_all_processes()
assert self.mock_prepare_data_fetch_process.called is True, 'データ取得準備処理が1回のみ実行されること'
assert self.mock_prepare_data_fetch_process.call_count == 1, 'データ取得準備処理が1回のみ実行されること'
assert self.mock_check_object_info_process.call_count == 3, 'オブジェクト情報形式チェック処理が複数回実行されること'
assert self.mock_set_datetime_period_process.call_count == 3, 'データ取得期間設定処理が複数回実行されること'
assert self.mock_fetch_crm_data_process.call_count == 3, 'CRMデータ取得処理が複数回実行されること'
assert self.mock_backup_crm_data_process.call_count == 3, 'CRM電文データバックアップ処理が複数回実行されること'
assert self.mock_convert_crm_csv_data_process.call_count == 3, 'CSV変換処理が複数回実行されること'
assert self.mock_backup_crm_csv_data_process.call_count == 3, 'CSVバックアップ処理が複数回実行されること'
assert self.mock_copy_crm_csv_data_process.call_count == 3, 'CSVアップロード処理が複数回実行されること'
assert self.mock_upload_last_fetch_datetime_process.call_count == 3, '前回取得日次ファイル更新処理が複数回実行されること'
assert self.mock_upload_result_data_process.called is True, '取得処理実施結果アップロード処理が1回のみ実行されること'
assert self.mock_upload_result_data_process.call_count == 1, '取得処理実施結果アップロード処理が1回のみ実行されること'
def test_print_normal_logs(self, call_all_processes, caplog):
"""
Cases:
コントロール処理の正常系ログがすべての出力されていること
Arranges:
- call_all_processesフィクスチャでコントロール処理を実行しておく
Expects:
- コントロール処理の正常系ログがすべて出力されている
"""
call_all_processes()
assert generate_log_message_tuple(log_message='I-CTRL-01 CRMデータ取得処理を開始します') in caplog.record_tuples
assert generate_log_message_tuple(log_message='I-CTRL-02 データ取得準備処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message='I-CTRL-03 取得対象オブジェクトのループ処理開始') in caplog.record_tuples
for name in ['Account', 'Contact', 'Call2_vod__c']:
object_name = name
upload_file_name = f'{name}_YYYYMMDDHHMMSS'
assert generate_log_message_tuple(log_message='I-CTRL-05 オブジェクト情報形式チェック処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-06 [{object_name}]のデータ取得を開始します') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-08 [{object_name}]のデータ取得期間設定処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-09 [{object_name}]のデータ取得処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-10 [{object_name}] の出力ファイル名は [{upload_file_name}] となります') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-11 [{object_name}] CRM電文データバックアップ処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-12 [{object_name}] CSV変換処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-13 [{object_name}] CSVデータバックアップ処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-14 [{object_name}] CSVデータアップロード処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-15 [{object_name}] 前回取得日時ファイル更新処理呼び出し') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-16 [{object_name}] 処理正常終了') in caplog.record_tuples
expect_process_result = {
'Account': 'success',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-18 CRM_取得処理実施結果ファイルアップロード処理開始') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-19 すべてのデータの取得に成功しました') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-20 CRMデータ取得処理を終了します') in caplog.record_tuples
def test_do_not_call_upload_process_result_process(self, caplog, run_control_process):
"""
Cases:
処理対象オブジェクトが0件の場合取得処理実施結果アップロード処理が実行されないこと
Arranges:
- データ取得準備処理で返される取得対象オブジェクト情報を0件にする
- 各種プロセスメソッドと内部で使用している値オブジェクトをモック化する
Expects:
- データ取得準備処理が1回のみ実行されること
- 取得処理実施結果アップロード処理が実行されないこと
- 処理対象が存在しない旨を示すログメッセージが出力されていること
"""
self.mock_prepare_data_fetch_process = MagicMock(return_value=([], COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock()
self.mock_set_datetime_period_process = MagicMock()
self.mock_fetch_crm_data_process = MagicMock()
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
# 実行回数の確認
assert self.mock_prepare_data_fetch_process.called, 'データ取得準備処理が1回のみ実行されること'
assert self.mock_prepare_data_fetch_process.call_count == 1, 'データ取得準備処理が1回のみ実行されること'
assert self.mock_upload_result_data_process.called is False, '取得処理実施結果アップロード処理が実行されないこと'
assert self.mock_upload_result_data_process.call_count == 0, '取得処理実施結果アップロード処理が実行されないこと'
# ログ出力の確認
assert generate_log_message_tuple(log_message='I-CTRL-21 処理対象のデータが存在しませんでした') in caplog.record_tuples, '処理対象が存在しない旨を示すログメッセージが出力されていること'
assert generate_log_message_tuple(log_message=f'I-CTRL-20 CRMデータ取得処理を終了します') in caplog.record_tuples
def test_do_not_call_upload_csv_process_cause_is_skip_true(self, caplog, run_control_process):
"""
Cases:
オブジェクト情報.is_skipがTrueの場合CSVアップロード処理が実行されないこと
Arranges:
- データ取得準備処理で返される取得対象オブジェクト情報のis_skipをTrueにする
- 各種プロセスメソッドと内部で使用している値オブジェクトをモック化する
Expects:
- オブジェクト情報形式チェック処理以降のプロセスが実行されないこと
- 処理をスキップする旨を示すログメッセージが出力されていること
"""
mock_check_object_info = {
'object_name': 'Account',
'columns': [],
'is_skip': True
}
mock_return_values = [TargetObject(mock_check_object_info, COMMON_EXECUTE_DATETIME)]
self.mock_prepare_data_fetch_process = MagicMock(return_value=([mock_check_object_info], COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock()
self.mock_fetch_crm_data_process = MagicMock()
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
# 実行回数の確認
assert self.mock_check_object_info_process.called is True
assert self.mock_check_object_info_process.call_count == 1
# オブジェクト情報形式チェック処理以降のプロセスが実行されないこと
assert self.mock_set_datetime_period_process.call_count == 0
assert self.mock_fetch_crm_data_process.call_count == 0
assert self.mock_backup_crm_data_process.call_count == 0
assert self.mock_convert_crm_csv_data_process.call_count == 0
assert self.mock_backup_crm_csv_data_process.call_count == 0
assert self.mock_copy_crm_csv_data_process.call_count == 0
assert self.mock_upload_last_fetch_datetime_process.call_count == 0
# 結果ファイルの出力は行う
assert self.mock_upload_result_data_process.called is True
assert self.mock_upload_result_data_process.call_count == 1
# ログ出力の確認
assert generate_log_message_tuple(log_message='I-CTRL-07 [Account]のデータ取得処理をスキップします') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-20 CRMデータ取得処理を終了します') in caplog.record_tuples
def test_do_not_call_upload_csv_process_cause_is_skip_true_in_loop(self, caplog, run_control_process):
"""
Cases:
オブジェクト情報.is_skipがTrueのものが含まれる場合対象オブジェクトのCSVアップロード処理が実行されないこと
Arranges:
- データ取得準備処理で返される取得対象オブジェクト情報のうちつ目をis_skipをTrueにする
- 各種プロセスメソッドと内部で使用している値オブジェクトをモック化する
Expects:
- オブジェクト情報形式チェック処理が2回実行されること
- 処理をスキップする旨を示すログメッセージが出力されていること
- オブジェクト情報.is_skipがFalseのものはCSVアップロード処理のログメッセージが出力されていること
"""
mock_check_object_infos = {
'objects': [
{
'object_name': 'Account',
'columns': [],
'is_skip': False
},
{
'object_name': 'Contact',
'columns': [],
'is_skip': True
},
{
'object_name': 'Call2_vod__c',
'columns': [],
'is_skip': False
}
]
}
FetchTargetObjects(mock_check_object_infos)
mock_return_values = [
TargetObject(mock_check_object_infos['objects'][0], COMMON_EXECUTE_DATETIME),
TargetObject(mock_check_object_infos['objects'][1], COMMON_EXECUTE_DATETIME),
TargetObject(mock_check_object_infos['objects'][2], COMMON_EXECUTE_DATETIME),
]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(FetchTargetObjects(mock_check_object_infos), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock()
self.mock_fetch_crm_data_process = MagicMock(side_effect=[[{"Name": "Test"}], [{"Name": "Test"}]])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
# 実行回数の確認
assert self.mock_prepare_data_fetch_process.called is True
assert self.mock_prepare_data_fetch_process.call_count == 1
assert self.mock_check_object_info_process.call_count == 3
# オブジェクト情報形式チェック処理以降のプロセスが実行されないこと
assert self.mock_set_datetime_period_process.call_count == 2
assert self.mock_fetch_crm_data_process.call_count == 2
assert self.mock_backup_crm_data_process.call_count == 2
assert self.mock_convert_crm_csv_data_process.call_count == 2
assert self.mock_backup_crm_csv_data_process.call_count == 2
assert self.mock_copy_crm_csv_data_process.call_count == 2
assert self.mock_upload_last_fetch_datetime_process.call_count == 2
assert self.mock_upload_result_data_process.called is True
assert self.mock_upload_result_data_process.call_count == 1
# ログ出力の確認
assert generate_log_message_tuple(
log_message='I-CTRL-14 [Account] CSVデータアップロード処理呼び出し') in caplog.record_tuples, 'オブジェクト情報.is_skipがFalseのものはCSVアップロード処理のログメッセージが出力されていること'
assert generate_log_message_tuple(
log_message='I-CTRL-07 [Contact]のデータ取得処理をスキップします') in caplog.record_tuples, '処理をスキップする旨を示すログメッセージが出力されていること'
assert generate_log_message_tuple(
log_message='I-CTRL-14 [Call2_vod__c] CSVデータアップロード処理呼び出し'
) in caplog.record_tuples, 'オブジェクト情報.is_skipがFalseのものはCSVアップロード処理のログメッセージが出力されていること'
assert generate_log_message_tuple(log_message=f'I-CTRL-20 CRMデータ取得処理を終了します') in caplog.record_tuples
def test_do_not_call_upload_csv_process_cause_crm_data_empty(self, caplog, run_control_process):
"""
Cases:
CRMデータ取得処理で取得できた件数が0件の場合CSVアップロード処理が実行されないこと
Arranges:
- CRMデータ取得処理で返されるオブジェクトを空のリストにする
- 各種プロセスメソッドと内部で使用している値オブジェクトをモック化する
Expects:
- CRM電文データバックアップ処理以降のプロセスが実行されないこと
- 処理をスキップする旨を示すログメッセージが出力されていること
"""
mock_check_object_infos = {
'objects': [
{
'object_name': 'Account',
'columns': [],
'is_skip': False
}
]
}
FetchTargetObjects(mock_check_object_infos)
mock_return_values = [
TargetObject(mock_check_object_infos['objects'][0], COMMON_EXECUTE_DATETIME)
]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(FetchTargetObjects(mock_check_object_infos), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock()
self.mock_fetch_crm_data_process = MagicMock(return_value=[])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
# 実行回数の確認
assert self.mock_prepare_data_fetch_process.called is True
assert self.mock_prepare_data_fetch_process.call_count == 1
assert self.mock_check_object_info_process.call_count == 1
assert self.mock_set_datetime_period_process.call_count == 1
assert self.mock_fetch_crm_data_process.call_count == 1
# CRM電文データバックアップ処理以降のプロセスが実行されないこと
assert self.mock_backup_crm_data_process.call_count == 0
assert self.mock_convert_crm_csv_data_process.call_count == 0
assert self.mock_backup_crm_csv_data_process.call_count == 0
assert self.mock_copy_crm_csv_data_process.call_count == 0
assert self.mock_upload_last_fetch_datetime_process.call_count == 0
assert self.mock_upload_result_data_process.called is True
assert self.mock_upload_result_data_process.call_count == 1
# ログ出力の確認
assert generate_log_message_tuple(
log_message='I-CTRL-22 [Account]のレコード件数が0件のため、ファイルアップロードをスキップします') in caplog.record_tuples, '処理をスキップする旨を示すログメッセージが出力されていること'
def test_do_not_call_upload_csv_process_cause_crm_data_empty_in_loop(self, caplog, run_control_process):
"""
Cases:
CRMデータ取得処理で取得できた件数が0件のものが含まれる場合対象オブジェクトのCSVアップロード処理が実行されないこと
Arranges:
- CRMデータ取得処理で返されるオブジェクトのうちつ目を空のリストにする
- 各種プロセスメソッドと内部で使用している値オブジェクトをモック化する
Expects:
- CRMデータ取得処理が2回実行されること
- 処理をスキップする旨を示すログメッセージが出力されていること
- 取得オブジェクトが1件以上取れているものはCSVアップロード処理のログメッセージが出力されていること
"""
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=[COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3])
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(side_effect=[[{"Name": "Test"}], [], [{"Name": "Test"}]])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
# 実行回数の確認
assert self.mock_check_object_info_process.call_count == 3
assert self.mock_set_datetime_period_process.call_count == 3
assert self.mock_fetch_crm_data_process.call_count == 3
# CRM電文データバックアップ処理以降のプロセスは件数があるもののみ実行されること
assert self.mock_backup_crm_data_process.call_count == 2
assert self.mock_convert_crm_csv_data_process.call_count == 2
assert self.mock_backup_crm_csv_data_process.call_count == 2
assert self.mock_copy_crm_csv_data_process.call_count == 2
assert self.mock_upload_last_fetch_datetime_process.call_count == 2
assert self.mock_upload_result_data_process.called is True
assert self.mock_upload_result_data_process.call_count == 1
# ログ出力の確認
assert generate_log_message_tuple(
log_message='I-CTRL-14 [Account] CSVデータアップロード処理呼び出し') in caplog.record_tuples, '取得オブジェクトが1件以上取れているものはCSVアップロード処理のログメッセージが出力されていること'
assert generate_log_message_tuple(
log_message='I-CTRL-22 [Contact]のレコード件数が0件のため、ファイルアップロードをスキップします') in caplog.record_tuples, '処理をスキップする旨を示すログメッセージが出力されていること'
assert generate_log_message_tuple(
log_message='I-CTRL-14 [Call2_vod__c] CSVデータアップロード処理呼び出し'
) in caplog.record_tuples, '取得オブジェクトが1件以上取れているものはCSVアップロード処理のログメッセージが出力されていること'
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'E-ERR-01 [{PRE_JP_NAME}]でエラーが発生したため、処理を終了します'),
(ForTestException, 'E-ERR-02 予期せぬエラーが発生したため、処理を終了します エラー内容: [例外発生]')
])
def test_raise_prepare_data_fetch_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. データ取得準備処理でシステム例外が発生した場合エラーで終了すること
2. データ取得準備処理で想定外の例外が発生した場合エラーで終了すること
Arranges:
- パラメータ1データ取得準備処理でシステム例外が発生するようにする
- パラメータ2データ取得準備処理で想定外の例外が発生するようにする
Expects:
- データ取得準備処理で例外が発生すること
- データ取得準備処理で発生した例外のログメッセージが出力されていること
"""
expect_exception = exception('E-PRE-01', PRE_JP_NAME, '例外発生')
self.mock_prepare_data_fetch_process = MagicMock(side_effect=expect_exception)
self.mock_check_object_info_process = MagicMock()
with pytest.raises(exception):
run_control_process()
assert self.mock_check_object_info_process.called is False
assert generate_log_message_tuple(
log_level=logging.ERROR,
log_message=message) in caplog.record_tuples, 'データ取得準備処理で発生した例外のログメッセージが出力されていること'
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'I-ERR-03 [Account] の[{CHK_JP_NAME}]でエラーが発生しました 次のオブジェクトの処理に移行します'),
(ForTestException, 'I-ERR-04 [Account] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [例外発生]')
])
def test_raise_check_object_info_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. オブジェクト情報形式チェック処理でシステム例外が発生した場合エラーログが送出され後続の終了に移行すること
2. オブジェクト情報形式チェック処理で想定外の例外が発生した場合エラーログが送出され後続の終了に移行すること
Arranges:
- パラメータ1オブジェクト情報形式チェック処理でシステム例外が発生するようにする
- パラメータ2オブジェクト情報形式チェック処理で想定外の例外が発生するようにする
Expects:
- オブジェクト情報形式チェック処理で例外が発生する
- オブジェクト情報形式チェック処理で発生した例外のログメッセージが出力されている
- 例外が発生したオブジェクト以外は正常に終了する
"""
raise_object = exception('E-PRE-01', CHK_JP_NAME, '例外発生')
mock_return_values = [raise_object, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_2]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(return_value=[{'Name': 'Test'}])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
assert self.mock_check_object_info_process.call_count == 3
assert self.mock_set_datetime_period_process.call_count == 2
expect_process_result = {
'Account': 'fail',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=message) in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(
log_level=logging.ERROR, log_message=f'E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください') in caplog.record_tuples
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'I-ERR-03 [Account] の[{DATE_JP_NAME}]でエラーが発生しました 次のオブジェクトの処理に移行します'),
(ForTestException, 'I-ERR-04 [Account] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [例外発生]')
])
def test_raise_set_datetime_period_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. データ取得期間設定処理でシステム例外が発生した場合エラーログが送出され後続の終了に移行すること
2. データ取得期間設定処理で想定外の例外が発生した場合エラーログが送出され後続の終了に移行すること
Arranges:
- パラメータ1データ取得期間設定処理でシステム例外が発生するようにする
- パラメータ2データ取得期間設定処理で想定外の例外が発生するようにする
Expects:
- データ取得期間設定チェック処理で例外が発生する
- データ取得期間設定チェック処理で発生した例外のログメッセージが出力されている
- 例外が発生したオブジェクト以外は正常に終了する
"""
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(side_effect=[exception(
'E-DATE-01', DATE_JP_NAME, '例外発生'), COMMON_LAST_FETCH_DATETIME, COMMON_LAST_FETCH_DATETIME])
self.mock_fetch_crm_data_process = MagicMock(return_value=[{'Name': 'Test'}])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
assert self.mock_set_datetime_period_process.call_count == 3
assert self.mock_fetch_crm_data_process.call_count == 2
expect_process_result = {
'Account': 'fail',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=message) in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(
log_level=logging.ERROR, log_message=f'E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください') in caplog.record_tuples
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'I-ERR-03 [Account] の[{FETCH_JP_NAME}]でエラーが発生しました 次のオブジェクトの処理に移行します'),
(ForTestException, 'I-ERR-04 [Account] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [例外発生]')
])
def test_raise_fetch_crm_data_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. CRMデータ取得処理でシステム例外が発生した場合エラーログが送出され後続の終了に移行すること
2. CRMデータ取得処理で想定外の例外が発生した場合エラーログが送出され後続の終了に移行すること
Arranges:
- パラメータ1CRMデータ取得処理でシステム例外が発生するようにする
- パラメータ2CRMデータ取得処理で想定外の例外が発生するようにする
Expects:
- CRMデータ取得処理で例外が発生すること
- CRMデータ取得処理で発生した例外のログメッセージが出力されていること
"""
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(side_effect=[exception(
'E-FETCH-01', FETCH_JP_NAME, '例外発生'), [{'Name': 'Test'}], [{'Name': 'Test'}]])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
assert self.mock_fetch_crm_data_process.call_count == 3
assert self.mock_backup_crm_data_process.call_count == 2
expect_process_result = {
'Account': 'fail',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=message) in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(
log_level=logging.ERROR, log_message=f'E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください') in caplog.record_tuples
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'I-ERR-03 [Account] の[{RESBK_JP_NAME}]でエラーが発生しました 次のオブジェクトの処理に移行します'),
(ForTestException, 'I-ERR-04 [Account] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [例外発生]')
])
def test_raise_backup_crm_data_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. CRM電文データバックアップ処理でシステム例外が発生した場合エラーログが送出され後続の終了に移行すること
2. CRM電文データバックアップ処理で想定外の例外が発生した場合エラーログが送出され後続の終了に移行すること
Arranges:
- パラメータ1CRM電文データバックアップ処理でシステム例外が発生するようにする
- パラメータ2CRM電文データバックアップ処理で想定外の例外が発生するようにする
Expects:
- CRM電文データバックアップ処理で例外が発生すること
- CRM電文データバックアップ処理で発生した例外のログメッセージが出力されていること
"""
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(side_effect=[[{'Name': 'Test'}], [{'Name': 'Test'}], [{'Name': 'Test'}]])
self.mock_backup_crm_data_process = MagicMock(side_effect=[exception(
'E-RESBK-01', RESBK_JP_NAME, '例外発生'), None, None])
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
assert self.mock_backup_crm_data_process.call_count == 3
assert self.mock_convert_crm_csv_data_process.call_count == 2
expect_process_result = {
'Account': 'fail',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=message) in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(
log_level=logging.ERROR, log_message=f'E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください') in caplog.record_tuples
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'I-ERR-03 [Account] の[{CONV_JP_NAME}]でエラーが発生しました 次のオブジェクトの処理に移行します'),
(ForTestException, 'I-ERR-04 [Account] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [例外発生]')
])
def test_raise_convert_crm_csv_data_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. CSV変換処理でシステム例外が発生した場合エラーログが送出され後続の終了に移行すること
2. CSV変換処理で想定外の例外が発生した場合エラーログが送出され後続の終了に移行すること
Arranges:
- パラメータ1CSV変換処理でシステム例外が発生するようにする
- パラメータ2CSV変換処理で想定外の例外が発生するようにする
Expects:
- CSV変換処理で例外が発生すること
- CSV変換処理で発生した例外のログメッセージが出力されていること
"""
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(side_effect=[[{'Name': 'Test'}], [{'Name': 'Test'}], [{'Name': 'Test'}]])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock(side_effect=[exception(
'E-CONV-01', CONV_JP_NAME, '例外発生'), None, None])
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
assert self.mock_convert_crm_csv_data_process.call_count == 3
assert self.mock_backup_crm_csv_data_process.call_count == 2
expect_process_result = {
'Account': 'fail',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=message) in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(
log_level=logging.ERROR, log_message=f'E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください') in caplog.record_tuples
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'I-ERR-03 [Account] の[{CSVBK_JP_NAME}]でエラーが発生しました 次のオブジェクトの処理に移行します'),
(ForTestException, 'I-ERR-04 [Account] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [例外発生]')
])
def test_raise_backup_crm_csv_data_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. CSVバックアップ処理でシステム例外が発生した場合エラーログが送出され後続の終了に移行すること
2. CSVバックアップ処理で想定外の例外が発生した場合エラーログが送出され後続の終了に移行すること
Arranges:
- パラメータ1CSVバックアップ処理でシステム例外が発生するようにする
- パラメータ2CSVバックアップ処理で想定外の例外が発生するようにする
Expects:
- CSVバックアップ処理で例外が発生すること
- CSVバックアップ処理で発生した例外のログメッセージが出力されていること
"""
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(side_effect=[[{'Name': 'Test'}], [{'Name': 'Test'}], [{'Name': 'Test'}]])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock(side_effect=[exception(
'E-CSVBK-01', CSVBK_JP_NAME, '例外発生'), None, None])
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
assert self.mock_backup_crm_csv_data_process.call_count == 3
assert self.mock_copy_crm_csv_data_process.call_count == 2
expect_process_result = {
'Account': 'fail',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=message) in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(
log_level=logging.ERROR, log_message=f'E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください') in caplog.record_tuples
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'I-ERR-03 [Account] の[{UPLD_JP_NAME}]でエラーが発生しました 次のオブジェクトの処理に移行します'),
(ForTestException, 'I-ERR-04 [Account] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [例外発生]')
])
def test_raise_copy_crm_csv_data_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. CSVアップロード処理でシステム例外が発生した場合エラーログが送出され後続の終了に移行すること
2. CSVアップロード処理で想定外の例外が発生した場合エラーログが送出され後続の終了に移行すること
Arranges:
- パラメータ1CSVアップロード処理でシステム例外が発生するようにする
- パラメータ2CSVアップロード処理で想定外の例外が発生するようにする
Expects:
- CSVアップロード処理で例外が発生すること
- CSVアップロード処理で発生した例外のログメッセージが出力されていること
"""
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(side_effect=[[{'Name': 'Test'}], [{'Name': 'Test'}], [{'Name': 'Test'}]])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock(side_effect=[exception(
'E-UPLD-01', UPLD_JP_NAME, '例外発生'), None, None])
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock()
run_control_process()
assert self.mock_copy_crm_csv_data_process.call_count == 3
assert self.mock_upload_last_fetch_datetime_process.call_count == 2
expect_process_result = {
'Account': 'fail',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=message) in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(
log_level=logging.ERROR, log_message=f'E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください') in caplog.record_tuples
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'I-ERR-03 [Account] の[{UPD_JP_NAME}]でエラーが発生しました 次のオブジェクトの処理に移行します'),
(ForTestException, 'I-ERR-04 [Account] の処理中に予期せぬエラーが発生しました 次のオブジェクトの処理に移行します エラー内容: [例外発生]')
])
def test_raise_upload_last_fetch_datetime_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. 前回取得日時ファイル更新処理でシステム例外が発生した場合エラーログが送出され後続の終了に移行すること
2. 前回取得日時ファイル更新処理で想定外の例外が発生した場合エラーログが送出され後続の終了に移行すること
Arranges:
- パラメータ1前回取得日時ファイル更新処理でシステム例外が発生するようにする
- パラメータ2前回取得日時ファイル更新処理で想定外の例外が発生するようにする
Expects:
- 前回取得日時ファイル更新処理で例外が発生すること
- 前回取得日時ファイル更新処理で発生した例外のログメッセージが出力されていること
"""
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(side_effect=[[{'Name': 'Test'}], [{'Name': 'Test'}], [{'Name': 'Test'}]])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock(side_effect=[exception(
'E-UPD-01', UPD_JP_NAME, '例外発生'), None, None])
self.mock_upload_result_data_process = MagicMock()
run_control_process()
assert self.mock_upload_last_fetch_datetime_process.call_count == 3
expect_process_result = {
'Account': 'fail',
'Contact': 'success',
'Call2_vod__c': 'success'
}
assert generate_log_message_tuple(log_message=message) in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-CTRL-17 すべてのオブジェクトの処理が終了しました 実行結果:[{expect_process_result}]') in caplog.record_tuples
assert generate_log_message_tuple(
log_level=logging.ERROR, log_message=f'E-CTRL-01 一部のデータ取得に失敗しています 詳細はログをご確認ください') in caplog.record_tuples
@pytest.mark.parametrize(
'exception, message',
[
(ForTestMeDaCaCRMDataFetchException, f'E-ERR-01 [{END_JP_NAME}]でエラーが発生したため、処理を終了します'),
(ForTestException, 'E-ERR-02 予期せぬエラーが発生したため、処理を終了します エラー内容: [例外発生]')
])
def test_raise_upload_result_data_process(self, caplog, exception, message, run_control_process):
"""
Cases:
1. 取得処理実施結果アップロード処理でシステム例外が発生した場合エラーで終了すること
2. 取得処理実施結果アップロード処理で想定外の例外が発生した場合エラーで終了すること
Arranges:
- パラメータ1取得処理実施結果アップロード処理でシステム例外が発生するようにする
- パラメータ2取得処理実施結果アップロード処理で想定外の例外が発生するようにする
Expects:
- 取得処理実施結果アップロード処理で例外が発生すること
- 取得処理実施結果アップロード処理で発生した例外のログメッセージが出力されていること
"""
mock_return_values = [COMMON_TARGET_OBJECTS_1, COMMON_TARGET_OBJECTS_2, COMMON_TARGET_OBJECTS_3]
self.mock_prepare_data_fetch_process = MagicMock(return_value=(deepcopy(COMMON_FETCH_TARGET_OBJECTS), COMMON_EXECUTE_DATETIME, {}))
self.mock_check_object_info_process = MagicMock(side_effect=mock_return_values)
self.mock_set_datetime_period_process = MagicMock(return_value=COMMON_LAST_FETCH_DATETIME)
self.mock_fetch_crm_data_process = MagicMock(side_effect=[[{'Name': 'Test'}], [{'Name': 'Test'}], [{'Name': 'Test'}]])
self.mock_backup_crm_data_process = MagicMock()
self.mock_convert_crm_csv_data_process = MagicMock()
self.mock_backup_crm_csv_data_process = MagicMock()
self.mock_copy_crm_csv_data_process = MagicMock()
self.mock_upload_last_fetch_datetime_process = MagicMock()
self.mock_upload_result_data_process = MagicMock(side_effect=[exception(
'E-END-01', END_JP_NAME, '例外発生'), None, None])
with pytest.raises(exception):
run_control_process()
assert self.mock_upload_result_data_process.called is True
assert self.mock_upload_result_data_process.call_count == 1
assert generate_log_message_tuple(
log_level=logging.ERROR,
log_message=message) in caplog.record_tuples, '取得処理実施結果アップロード処理で発生した例外のログメッセージが出力されていること'

View File

@ -0,0 +1,7 @@
"""ログメッセージに関連するテストヘルパー"""
import logging
def generate_log_message_tuple(logger_name='root', log_level=logging.INFO, log_message=''):
return (logger_name, log_level, log_message)