Magento 1.9の単体テストのベストプラクティス


11

いくつかのカスタムモジュールを使用してMagento 1.9サイトを管理しています。一部の機能はビジネスに不可欠であり、いくつかの単体テストが緊急に必要です。例えば、単価計算機。

私は通常Symfonyで開発しており、可能であればPHPUnit(Composer付き)をどうにかして使用したいと思っています。

一部の機能は、いくつかのカスタムデータベーステーブルにインポートされたデータに基づいているため、フィクスチャを何らかの方法でロードしたいと思います。

だから私はいくつかの単体テストを書くためのベストプラクティスのアプローチを探しています。チュートリアルなどを受け付けます。どんな助けでもありがたいです。

回答:


10

しばらく前に同じ問題に直面しました。

Ecomdev PHPUnitモジュールの使用を検討しましたが、使用が難しく、文書化も不十分でした(ただし、Ivanの機能とMagentoエコシステムへの彼の多大な貢献は今でも気に入っています)。

そのため、Vinaiの助けを借りて、次のテストフレームワークモジュールを開発することになりました。https//github.com/digitalpianism/testframework

元々の目的は統合テストでしたが、私はそれを単体テストにも使用しています。あなたはここでそれを実際に見ることができます:https//github.com/digitalpianism/easytoplinks/blob/master/app/code/community/DigitalPianism/EasyToplinks/Test/Unit/Block/Page/Template/LinksTest.php

フィクスチャに関しては、データベースにサンプルデータを作成しないようにトランザクションロールバックを使用しています。


これは本当に有望に見えます。やってみます。ありがとう。
frigg、2016年

13

設置

Magento 1はそのままの状態でcomposerを使用しないため、composerを使用してphpunitをインストールするか、pharバージョンをダウンロードするだけで大​​きな違いはないと思います。
composerを使用してサイト内の他のサードパーティのモジュールまたはライブラリを管理している場合は、composerがおそらく最も理にかなっています。PHP7を使用しない限り、phpunitの古いバージョンに制限されます(そのため、上記の4.8バージョンにリンクしました)。

統合テストvs /および/または単体テスト

Magento 1は非常に重いアプリケーションであるため、phpunitブートストラップを統合用とユニットテスト用に分離することは理にかなっています。
ユニットテストブートストラップは、オートローダーを初期化するだけで済みますが、統合テストブートストラップは、構成の読み込みやdb接続を含むアプリケーション環境全体を初期化する必要があります。
そのため、Magentoでの統合テストは、単体テストよりもはるかに遅く実行される傾向があります(他のアプリケーションではさらに高くなります)。

Magentoをphpunitにブートストラップする

  • Magentoのオートローダーは、クラスが配置されているファイルが見つからない場合に例外をスローするため、PSR-0に準拠していません。これによりclass_exists、phpunitの一部の使用法が壊れます。(ハックの場合)いくつかの可能な回避策があります。

    • Magentoオートローダーの登録を解除し、\Varien_Autoload::autoload()内部でスローされた例外を無視してデコレーターでラップし、ラッパーを新しいオートローダーとして登録します。これは、オートローダーを登録し、特定のオートローダーの順序に依存するサードパーティのライブラリと競合する可能性が低くなります。
    • Magento 1に組み込まれたものをラップするカスタムエラーハンドラーを使用します。カスタムエラーハンドラーは、Magentoオートローダーによってトリガーされたエラーを飲み込みます。これは、Raphaelのテストフレームワークが使用するソリューションです。これは、他のサードパーティの拡張機能と最も互換性があるようです。
    • インクルードパスハックを使用して\Varien_Autoload::autoload()、ファイルが存在しない場合にエラーをスローしないようにオーバーライドします。ただし、これは同じクラスをオーバーライドする複数のモジュールと競合します。私はこのアプローチを自分で使っていません。
  • テスト中に開始されるセッションによるエラーを回避するに$_SESSON = []は、ブートストラップに設定するだけです。

  • Mage::app()->setResponse($testResponse)実際のオブジェクトを拡張して、出力やヘッダーを送信しないカスタム応答オブジェクトを設定します。

  • ランタイム状態を完全に変更する統合テスト間でMagentoを再初期化するには、を使用しますMage::reset(); Mage::app()。その後、エラーハンドラーを再装飾する必要があることに注意してください。

備品

DBフィクスチャの場合、フィクスチャメソッドで通常のモデルを使用してフィクスチャを作成する傾向がありますcreateSimpleProduct($sku)。ラファエルが言ったように、とを使用setUp()tearDown()て、テスト後にロールバックされるトランザクションにテストをラップします(たとえばMage::getSingleton('core/resource')->getConnection('default_setup')->beginTransaction())。

ストア構成のフィクスチャでは、を使用してメモリ内のみのフィクスチャを設定する傾向がありますMage::app()->getStore()->setConfig($path, $value)

EcomDev_PHPUnit拡張子はまた、YAMLファイルを使用してDB器具を作成するオプションを提供していますが、自分のために、私は難しいモデルクラスを使用して作成された器具に比べて維持するために、それらを見つけます。YMMV。

ダブルスをテストする

レジストリを使用してMage::getSingleton()Mage::getResourceSingleton()およびを介して作成されたオブジェクトにテストdoubleを挿入できますMage::helper()
他のいくつかの中央オブジェクトを設定できますMage::app()(例:リクエスト)。テストダブルス
を介して、Mage::getModel()またはMage::getResourceModel()テストダブルスで作成されたクラスを置き換えるには、カスタム構成オブジェクトラッパーを使用する必要があります。ラファエルのテストフレームワークでこの例を参照してそれを実現する方法を確認してください。

概要

Magentoがブートストラップされると、ほとんどすべてをかなりうまくテストできます。ただし、コアコードが使用するメソッドチェーンが大量にあるため、深いモックを作成する準備をしてください。
セットアップはハックですが、うまく機能し、テストは私に大きな自信と価値を与えてくれます。Symphonyアプリのテストスイートにかなり匹敵します。


私は試したことはありませんが、なぜMagento Test Frameworkを使わないのですか?(docs.magento.com/m1/ce/user_guide/magento/...
フラ

3
はい、試してみましたが、機能テスト(ユニットや統合ではありません)、遅く、複雑で、テストは不安定で壊れやすい傾向があります。全体として、私はそれに費やす時間を無駄にしています。
ビナイ

@Vinai遅いことは知っていますが、一般的にコントローラーにはモデルとコレクションへの呼び出しがあり、テスト中は必要ありません。私はテストフレームワーク(DigitalPianism)を使用していますが、モデルをTestDoubleできますが、モデルを使用するコントローラーアクションへのgetリクエストを作成しながら、そのモデル/コレクションの呼び出しをモックするにはどうすればよいですか?
arqam
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.