createExe プロジェクト - モジュール管理ガイド

createExeプロジェクトでモジュールの追加・改修を行う際の手順書です。

目次


新モジュール追加手順

新しいモジュール(例:DUNGEON)を追加する場合の手順です。

1. ディレクトリ構造作成

# メインモジュールディレクトリ作成
mkdir common/{new_module}
mkdir common/{new_module}/service
mkdir common/{new_module}/service/component  # 必要に応じて

# テストディレクトリ作成
mkdir test/common/{new_module}
mkdir test/common/{new_module}/service
mkdir test/common/{new_module}/service/component  # 必要に応じて

# 例: DUNGEONモジュールの場合
mkdir common/dungeon
mkdir common/dungeon/service
mkdir common/dungeon/service/component
mkdir test/common/dungeon
mkdir test/common/dungeon/service
mkdir test/common/dungeon/service/component

2. 基本ファイル作成

Controller層ファイル作成

# common/{new_module}/action.py
from common.abstract.{new_module}.abstractAction import AbstractAction
from common.{new_module}.service.action import Action as ServiceAction

class Action(AbstractAction):
    @staticmethod
    def execute(form, request):
        service = ServiceAction(request)
        result = service.execute()
        # フォームの状態更新処理
        if result.is_ok():
            # 成功時の処理
            pass

# common/{new_module}/display.py
from common.abstract.{new_module}.abstractDisplay import AbstractDisplay
from common.{new_module}.service.display import Display as ServiceDisplay

class Display(AbstractDisplay):
    @staticmethod
    def execute(form, request):
        service = ServiceDisplay(request)
        # 表示処理の実装
        pass

# common/{new_module}/sound.py
from common.abstract.{new_module}.abstractSound import AbstractSound
from common.{new_module}.service.sound import Sound as ServiceSound

class Sound(AbstractSound):
    @staticmethod
    def execute(form, request):
        service = ServiceSound(request)
        # 音声処理の実装
        pass

# common/{new_module}/status.py
from common.abstract.{new_module}.abstractStatus import AbstractStatus
from common.{new_module}.service.status import Status as ServiceStatus

class Status(AbstractStatus):
    @staticmethod
    def execute(status_form, request):
        service = ServiceStatus(request)
        result = service.get_next_status()
        if result.is_ok():
            next_status = result.data
            status_form.update_status(next_status)

Service層ファイル作成

# common/{new_module}/service/action.py
from common.layer.response.response import Response
from common.layer.code.code import Code

class Action:
    def __init__(self, request):
        self._request = request

    def execute(self):
        # ビジネスロジックの実装
        try:
            # 処理の実装
            result_data = self._process_request()
            return Response(data=result_data, result=Code.OK)
        except ValueError as e:
            return Response(data=str(e), result=Code.ARGUMENT_ERROR)

    def _process_request(self):
        # 具体的な処理を実装
        pass

# common/{new_module}/service/status.py
class Status:
    def __init__(self, request):
        self._request = request

    def get_next_status(self):
        # 状態遷移ロジックの実装
        if self._request.some_condition:
            return Response(data=target_status, result=Code.OK)
        return Response(data=current_status, result=Code.DO_NOTHING)

3. リクエスト・レスポンスオブジェクト作成

# common/layer/request/新しいモジュール名/モジュール名ActionRequest.py
# 例: common/layer/request/dungeon/dungeonActionRequest.py
from dataclasses import dataclass

@dataclass
class DungeonActionRequest:
    """
    DUNGEONモジュールのアクションリクエスト

    実際の実装時は、以下のようにモジュール名に合わせて変更:
    - クラス名: {モジュール名}ActionRequest
    - ファイル名: {モジュール名}ActionRequest.py
    """
    _param1: bool
    _param2: str
    _param3: int

    @property
    def param1(self):
        return self._param1

    @property
    def param2(self):
        return self._param2

    @property
    def param3(self):
        return self._param3

4. テストファイル作成

# test/common/{new_module}/action_test.py
import unittest
from common.{new_module}.service.action import Action

class ActionTest(unittest.TestCase):
    def test_normal_case_returns_expected_result(self):
        """
        正常系: 正しい入力での期待結果確認
            - 条件: 有効な入力データ
            - 期待結果: 期待される戻り値
            - 例外: なし
        """
        # Arrange
        request = create_valid_request()
        action = Action(request)

        # Act
        result = action.execute()

        # Assert
        self.assertTrue(result.is_ok())
        self.assertEqual(expected_data, result.data)

    def test_invalid_input_raises_value_error(self):
        """
        異常系: 無効な入力での例外発生確認
            - 条件: 無効な入力データ
            - 期待結果: ARGUMENT_ERROR結果
            - 例外: なし(Responseで返される)
        """
        # Arrange
        request = create_invalid_request()
        action = Action(request)

        # Act
        result = action.execute()

        # Assert
        self.assertTrue(result.is_argument_error())

if __name__ == '__main__':
    unittest.main()

5. ドキュメント作成

モジュール概要ドキュメント

# docs/modules/{new_module}_overview.rst を作成
touch docs/modules/{new_module}_overview.rst

index.rstに追加

# docs/index.rst の「モジュール別概要」セクションに追加
.. toctree::
   :maxdepth: 2
   :caption: モジュール別概要:

   modules/config_overview
   modules/home_overview
   modules/save_overview
   modules/end_overview
   modules/{new_module}_overview  # 新規追加

API仕様に追加

# docs/api/module_api.rst に追加
{MODULE_NAME}モジュール
-----------------------

Controller層
~~~~~~~~~~~~

.. automodule:: common.{new_module}.action
   :members:
   :undoc-members:
   :show-inheritance:

.. automodule:: common.{new_module}.display
   :members:
   :undoc-members:
   :show-inheritance:

.. automodule:: common.{new_module}.sound
   :members:
   :undoc-members:
   :show-inheritance:

.. automodule:: common.{new_module}.status
   :members:
   :undoc-members:
   :show-inheritance:

Service層
~~~~~~~~~

.. automodule:: common.{new_module}.service.action
   :members:
   :undoc-members:
   :show-inheritance:

.. automodule:: common.{new_module}.service.display
   :members:
   :undoc-members:
   :show-inheritance:

.. automodule:: common.{new_module}.service.sound
   :members:
   :undoc-members:
   :show-inheritance:

.. automodule:: common.{new_module}.service.status
   :members:
   :undoc-members:
   :show-inheritance:

6. 変更履歴更新

# docs/changelog.rst に追加
v1.4.0 (2026-XX-XX)
-------------------

新機能
~~~~~~

* {MODULE_NAME}機能を新規追加
  * 主要機能1の実装
  * 主要機能2の実装
  * 3層アーキテクチャでの統一実装

技術的改善
~~~~~~~~~~

* {MODULE_NAME}モジュールのテストカバレッジを追加
* APIドキュメントに{MODULE_NAME}機能を追加

既存モジュール改修手順

既存モジュールに機能追加・修正を行う場合の手順です。

1. 影響範囲の確認

# 関連ファイルの確認
find . -name "*{module_name}*.py" -o -name "*{module_name}*.rst" -o -name "*{module_name}*.md"

# 依存関係の確認
grep -r "from common.{module_name}" .
grep -r "import common.{module_name}" .

2. 既存テストの実行

# 該当モジュールのテスト実行
python -m pytest test/common/{module_name}/ -v

# 関連するテストの実行
python -m pytest test/ -k "{module_name}" -v

3. 修正実装

  • 後方互換性 を保つよう注意

  • 既存のインターフェース を変更する場合は、deprecated警告を追加

  • 新機能追加 の場合は、デフォルト値で既存動作を保持

4. テスト更新・追加

# 新機能のテストケース追加
def test_new_feature_works_correctly(self):
    """
    新機能: 新機能が正しく動作することを確認
        - 条件: 新機能を有効にした場合
        - 期待結果: 期待される新しい動作
        - 例外: なし
    """
    # テスト実装

# 後方互換性のテストケース追加
def test_backward_compatibility_maintained(self):
    """
    後方互換性: 既存の動作が保持されることを確認
        - 条件: 従来の使用方法
        - 期待結果: 従来と同じ動作
        - 例外: なし
    """
    # テスト実装

5. ドキュメント更新

モジュール概要の更新

# docs/modules/{module_name}_overview.rst の更新
新機能
~~~~~~

* **新機能名**: 新機能の説明
* **改善項目**: 改善内容の説明

技術仕様
--------

バージョン変更
~~~~~~~~~~~~~~

v1.X.0での変更点:
- 新機能の追加
- 既存機能の改善
- 非推奨機能(deprecated)の警告追加

APIドキュメントの確認

# APIドキュメントの自動生成確認
cd docs
make html

# 生成されたHTMLで新機能が正しく表示されるか確認

ドキュメント更新手順

1. モジュール概要ドキュメント作成・更新

新モジュールの場合:docs/modules/{module_name}_overview.rst を作成

{MODULE_NAME}機能の概要
=======================

概要
----

{MODULE_NAME}機能は、XXXXを担当する機能群です。
主な目的や用途について説明。

主要機能
--------

機能1
~~~~~

* **サブ機能1**: 説明
* **サブ機能2**: 説明

技術仕様
--------

アーキテクチャ
~~~~~~~~~~~~~~

3層構造で実装されています:

1. **Controller層** (``common/{module_name}/*.py``)
2. **Service層** (``common/{module_name}/service/*.py``)
3. **Component層** (``common/{module_name}/service/component/*.py``)

データフロー
~~~~~~~~~~~~

.. code-block:: text

   入力
    ↓
   Controller (処理1)
    ↓
   Service (処理2)
    ↓
   Component (処理3)
    ↓
   出力

関連ページ
----------

* :doc:`../api/module_api` - 詳細なAPI仕様
* :doc:`../guides/development_guide` - 開発ガイド
* :doc:`../changelog` - 変更履歴

2. index.rstの更新

# docs/index.rst のtoctreeに追加
.. toctree::
   :maxdepth: 2
   :caption: モジュール別概要:

   modules/config_overview
   modules/home_overview
   modules/save_overview
   modules/end_overview
   modules/{new_module}_overview  # 新規追加

3. API仕様の更新

docs/api/module_api.rst に新モジュールのautomodule定義を追加

4. 変更履歴の更新

docs/changelog.rst の最新バージョンに変更内容を記録

5. ドキュメント生成確認

cd docs
make clean
make html

# 生成されたドキュメントの確認
# - リンクが正しく動作するか
# - APIドキュメントが正しく生成されるか
# - 画像・図表が正しく表示されるか

テスト追加手順

1. テストファイル作成

# テストファイル作成(モジュール構造に合わせて)
touch test/common/{module_name}/{function}_test.py
touch test/common/{module_name}/service/{function}_test.py
touch test/common/{module_name}/service/component/{component}_test.py

2. テストケース実装

基本テンプレート

# 例: test/common/dungeon/action_test.py
import unittest
from unittest.mock import MagicMock, patch
from common.dungeon.service.action import Action

class ActionTest(unittest.TestCase):
    """
    Actionのテストクラス

    実際の実装時は、以下のようにモジュール名に合わせて変更:
    - インポート: from common.{モジュール名}.service.{機能名} import {クラス名}
    - クラス名: {クラス名}Test
    """

    def setUp(self):
        """各テストメソッドの前に実行される初期化処理"""
        self.valid_request = self._create_valid_request()
        self.invalid_request = self._create_invalid_request()

    def test_normal_case_returns_expected_result(self):
        """
        正常系: 正しい入力での期待結果確認
            - 条件: 有効な入力データ
            - 期待結果: 期待される戻り値
            - 例外: なし
        """
        # Arrange
        component = Action(self.valid_request)

        # Act
        result = component.execute()

        # Assert
        self.assertTrue(result.is_ok())
        self.assertEqual(expected_data, result.data)

    def test_invalid_input_returns_argument_error(self):
        """
        異常系: 無効な入力でのエラー確認
            - 条件: 無効な入力データ
            - 期待結果: ARGUMENT_ERROR結果
            - 例外: なし
        """
        # Arrange
        component = Action(self.invalid_request)

        # Act
        result = component.execute()

        # Assert
        self.assertTrue(result.is_argument_error())

    def test_boundary_values_handled_correctly(self):
        """
        境界値: 境界値での動作確認
            - 条件: 最小値・最大値の入力
            - 期待結果: 適切な処理
            - 例外: なし
        """
        # Arrange & Act & Assert
        # 境界値テストの実装
        pass

    @patch('common.dungeon.service.action.external_dependency')
    def test_external_dependency_failure_handled(self, mock_dependency):
        """
        外部依存: 外部依存の失敗時の処理確認
            - 条件: 外部依存が失敗する場合
            - 期待結果: 適切なエラーハンドリング
            - 例外: なし(Responseで返される)
        """
        # Arrange
        mock_dependency.side_effect = Exception("External error")
        component = Action(self.valid_request)

        # Act
        result = component.execute()

        # Assert
        self.assertTrue(result.is_error())

    def _create_valid_request(self):
        """有効なリクエストオブジェクトを作成"""
        # リクエスト作成の実装
        pass

    def _create_invalid_request(self):
        """無効なリクエストオブジェクトを作成"""
        # リクエスト作成の実装
        pass

if __name__ == '__main__':
    unittest.main()

3. テスト実行・カバレッジ確認

# 単体テスト実行
python -m pytest test/common/{module_name}/ -v

# カバレッジ確認
python -m pytest test/common/{module_name}/ --cov=common.{module_name} --cov-report=html

# 全体テスト実行(影響確認)
python -m pytest test/ -v

品質チェック手順

1. コード品質チェック

# 静的解析
flake8 common/{module_name}/
pylint common/{module_name}/

# 型チェック
mypy common/{module_name}/

2. テストカバレッジチェック

# カバレッジ測定
python -m pytest test/common/{module_name}/ --cov=common.{module_name} --cov-report=term-missing

# 目標: 90%以上のカバレッジ

3. ドキュメント品質チェック

# ドキュメント生成エラーチェック
cd docs
make clean
make html

# リンク切れチェック
make linkcheck

4. 統合テスト

# 全モジュールのテスト実行
python -m pytest test/ -v

# 特定の機能に関連するテスト実行
python -m pytest test/ -k "{module_name}" -v

チェックリスト

新モジュール追加チェックリスト

  • [ ] ディレクトリ構造作成完了

  • [ ] Controller層ファイル作成完了(action.py, display.py, sound.py, status.py)

  • [ ] Service層ファイル作成完了

  • [ ] Component層ファイル作成完了(必要に応じて)

  • [ ] リクエスト・レスポンスオブジェクト作成完了

  • [ ] テストファイル作成完了

  • [ ] モジュール概要ドキュメント作成完了

  • [ ] index.rst更新完了

  • [ ] API仕様更新完了

  • [ ] 変更履歴更新完了

  • [ ] テスト実行・成功確認

  • [ ] ドキュメント生成・確認完了

  • [ ] コード品質チェック完了

既存モジュール改修チェックリスト

  • [ ] 影響範囲確認完了

  • [ ] 既存テスト実行・成功確認

  • [ ] 修正実装完了

  • [ ] 後方互換性確保

  • [ ] テスト更新・追加完了

  • [ ] モジュール概要ドキュメント更新完了

  • [ ] API仕様確認完了

  • [ ] 変更履歴更新完了

  • [ ] 全体テスト実行・成功確認

  • [ ] ドキュメント生成・確認完了

  • [ ] コード品質チェック完了


トラブルシューティング

よくある問題と対処法

問題

対処法

インポートエラー

__init__.py の追加、PYTHONPATHの確認

テスト失敗

モック設定の見直し、テストデータの確認

ドキュメント生成失敗

automoduleのパス間違い、インポート可能性の確認

型エラー

型注釈の修正、mypyの設定確認

サポート情報


最終更新: 2026-02-26