mcpField
F
frappe-testing

frappe-testing

github.com/lubusinテスト・品質69221 回インストール12 週間前に更新
リポジトリ

frappe-testing について

frappe-testing は、Frappe アプリ開発者向けのテストスキルです。組み込みのテスト機能を使った DocType、API、UI のテストや、失敗の調査、CI の準備を扱います。

主な機能

  1. 01DocType の単体・統合テスト
  2. 02API と権限のテスト
  3. 03Cypress UI テストの実行
  4. 04テストデータと分離の管理
  5. 05失敗調査と CI のガイダンス

活用シーン

  1. 01DocType コントローラーと API のテスト
  2. 02アプリまたはモジュールのテスト実行
  3. 03ロールベースの権限確認
  4. 04CI パイプライン向けテストの準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lubusin/frappe-skills --skill frappe-testing

インストール後、Claude Code で/frappe-testingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
ci-testing.md
cypress.md
fixtures.md
test-patterns.md
testing.md

詳細

Frappe のテスト

組み込みのテストフレームワークを使用して、Frappe アプリケーションのテストを作成し、実行します。

使用する場面

  • DocType コントローラーの単体テストを作成する
  • ワークフローや API の結合テストを作成する
  • 既存のテストスイートを実行する
  • テストの失敗をデバッグする
  • Frappe アプリの CI パイプラインを設定する

必要な入力

  • テスト対象のアプリ名
  • テストを実行するサイト名
  • テスト対象の特定のモジュール/DocType(任意)
  • テスト環境(開発用サイト、専用のテストサイト)

手順

0) テスト環境を設定する
# Install dev dependencies
bench setup requirements --dev

# Ensure site is ready
bench --site <site> migrate
1) テストを実行する
# Run all tests for an app
bench --site <site> run-tests --app my_app

# Run tests for specific module
bench --site <site> run-tests --module my_app.my_module.tests

# Run tests for specific DocType
bench --site <site> run-tests --doctype "My DocType"

# Verbose output
bench --site <site> run-tests --app my_app -v

# Run single test file
bench --site <site> run-tests --module my_app.doctype.sample_doc.test_sample_doc
2) DocType のテストを作成する

DocType と同じディレクトリに test_<doctype_name>.py を作成します。

# my_app/doctype/sample_doc/test_sample_doc.py
import frappe
from frappe.tests.utils import FrappeTestCase

class TestSampleDoc(FrappeTestCase):
    def setUp(self):
        # Create test data
        self.doc = frappe.get_doc({
            "doctype": "Sample Doc",
            "title": "Test Document"
        }).insert()
    
    def tearDown(self):
        # Cleanup
        frappe.delete_doc("Sample Doc", self.doc.name, force=True)
    
    def test_creation(self):
        self.assertEqual(self.doc.title, "Test Document")
    
    def test_validation(self):
        doc = frappe.get_doc({
            "doctype": "Sample Doc",
            "title": ""  # Invalid - required field
        })
        self.assertRaises(frappe.ValidationError, doc.insert)
    
    def test_workflow(self):
        self.doc.status = "Approved"
        self.doc.save()
        self.assertEqual(self.doc.status, "Approved")
3) API のテストを作成する
# my_app/tests/test_api.py
import frappe
from frappe.tests.utils import FrappeTestCase

class TestAPI(FrappeTestCase):
    def test_whitelist_method(self):
        from my_app.api import process_order
        
        # Create test order
        order = frappe.get_doc({
            "doctype": "Sales Order",
            "customer": "_Test Customer"
        }).insert()
        
        # Test the API
        result = process_order(order.name, "approve")
        
        self.assertEqual(result["status"], "success")
        
        # Cleanup
        frappe.delete_doc("Sales Order", order.name, force=True)
    
    def test_permission_denied(self):
        # Test as restricted user
        frappe.set_user("[email protected]")
        
        from my_app.api import sensitive_action
        self.assertRaises(frappe.PermissionError, sensitive_action, "doc-001")
        
        # Reset user
        frappe.set_user("Administrator")
4) 権限をテストする
def test_role_permissions(self):
    # Create user with specific role
    user = frappe.get_doc({
        "doctype": "User",
        "email": "[email protected]",
        "roles": [{"role": "Sales User"}]
    }).insert()
    
    frappe.set_user("[email protected]")
    
    # Test permission
    self.assertTrue(frappe.has_permission("Sales Order", "read"))
    self.assertFalse(frappe.has_permission("Sales Order", "delete"))
    
    # Cleanup
    frappe.set_user("Administrator")
    frappe.delete_doc("User", user.name, force=True)
5) フィクスチャを使用する
# my_app/doctype/sample_doc/test_records.json
[
    {
        "doctype": "Sample Doc",
        "title": "Test Record 1"
    },
    {
        "doctype": "Sample Doc",
        "title": "Test Record 2"
    }
]

テスト内で参照します。

class TestSampleDoc(FrappeTestCase):
    def test_fixture_loaded(self):
        doc = frappe.get_doc("Sample Doc", "Test Record 1")
        self.assertIsNotNone(doc)
6) UI テストを実行する(Cypress)
# Run UI tests for an app
bench --site <site> run-ui-tests my_app

# Headless mode
bench --site <site> run-ui-tests my_app --headless

検証

  • すべてのテストに合格する:bench --site <site> run-tests --app my_app
  • テストによる汚染がない(テストが分離されている)
  • フィードバックをすばやく得られるよう、テストを 5 分未満で実行できる
  • CI パイプラインが各コミットでテストを実行する

失敗時の対処/デバッグ

  • テストが見つからない:ファイル名が test_ で始まり、クラス名とメソッド名が規約に従っていることを確認します
  • データベースエラー:テストが分離されていない可能性があります。クリーンアップの漏れを確認します
  • テストでの権限エラー:セットアップで frappe.set_user("Administrator") を使用します
  • テストが遅い:不要なフィクスチャを避け、外部サービスをモックします

エスカレーション

参考資料

ガードレール

  • テストフィクスチャを使用する:各テストで手動作成するのではなく、フィクスチャを使ってテストデータを読み込みます
  • テストデータをクリーンアップする:作成したレコードを tearDown() で削除するか、frappe.db.rollback() を使用します
  • 外部サービスをモックする:テストで実際の API を呼び出してはいけません。HTTP 呼び出しをモックします
  • テストを分離する:各テストは独立している必要があり、テストの実行順序に依存してはいけません
  • ユーザーコンテキストを明示的に設定する:特定のユーザーとしてテストするには、frappe.set_user() を使用します

よくある間違い

間違い失敗する理由修正方法
FrappeTestCase を使用しないテストのセットアップ/ティアダウンが不足するfrappe.tests.utils.FrappeTestCase を継承する
DB ロールバックがないテストの汚染、不安定なテストtearDown またはトランザクションで frappe.db.rollback() を使用する
不安定な非同期テスト断続的に失敗するfrappe.tests.utils.run_until() または適切な非同期処理を使用する
振る舞いではなく実装をテストする壊れやすいテストになる内部メソッドの呼び出しではなく、結果をテストする
テストデータをハードコードする既存データと競合する_Test Record {uuid} のような一意の名前を使用する
権限テストを省略するセキュリティ上の欠陥につながるAdministrator だけでなく、異なるユーザーロールでテストする

コメント