Joomla 2.5コンポーネントをテストする方法


12

StackOverflowでこの質問をしましたが、ここで質問することをお勧めします。

ユニット/システム/統合テストに精通しているので、Joomlaコンポーネントをテストしたいと思います。これを行う標準的な方法はありますか?

私はテストを含まないこのjoomla mvcコンポーネントの例に取り組んでいます。JoomlaのドキュメントやさまざまなWebサイトで見つけることができるのは、テストコードとbootstrap.phpファイルの断片だけです。具体的に私が知りたいのは:

  • コンポーネントのテストコードを配置する場所
  • 独自のbootstrap.phpを提供する必要がありますか、それとも「joomla」を含めてテストを実行する方法がありますか

理想的には、テストと実行方法に関する指示があるオープンソースのJoomlaコンポーネントに誰かを誘導することができます(クイックルック、最初の5つはテストがありませんでした)。

私が見つけた最も近いものはこれで、私は私のダミーテストに基づいています。

これまでにやったこと

コンポーネントのディレクトリ構造:

  • こんにちは世界/
    • admin /
      • ...
      • テスト/
        • bootstrap.php
        • phpunit.xml
        • modelHelloWorldsTest.php
    • 地点/
      • ...
    • helloworld.xml

最初の試み

テストを実行するには、Joomlaインストールにコンポーネントをインストール/コピーします。次に、〜joomla / administration / components / com_helloworld / testsから次のコマンドを実行します。

php phpunit-4.2.phar --bootstrap bootstrap.php .

私が受け取るところ

Fatal error: Class 'ContentController' not found in C:\inetpub\wwwroot\ws_cairnstest\administrator\components\com_helloworld\tests\modelsHelloWorldsTest.php on line 5

これを集めると、bootstrap.phpが正しくなく、必要なJoomlaクラスがロードされていません。これについては、ある時点で調査しますが、これはテストを実行するためだけの多くのセットアップのようです。

bootstrap.php:

<?php
error_reporting(E_ALL);

define('_JEXEC', 1);
define('BASEPATH',realpath(dirname(__FILE__).'/../../'));
define('JOOMLA_PATH',realpath(dirname(__FILE__).'/../../../../../'));
define('JOOMLA_ADMIN_PATH',realpath(dirname(__FILE__).'/../../../../'));
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['REQUEST_METHOD'] = 'GET';

if (file_exists(JOOMLA_ADMIN_PATH . '/defines.php'))
{
    include_once JOOMLA_ADMIN_PATH . '/defines.php';
}

if (!defined('_JDEFINES'))
{
    define('JPATH_BASE', JOOMLA_ADMIN_PATH);
    require_once JPATH_BASE . '/includes/defines.php';
}

require_once JPATH_BASE . '/includes/framework.php';
require_once JPATH_BASE . '/includes/helper.php';
require_once JPATH_BASE . '/includes/toolbar.php';
define('JPATH_COMPONENT',JOOMLA_ADMIN_PATH.'/components/com_content');
$app = JFactory::getApplication('administrator');
include BASEPATH.'/controller.php';

modelsHelloWorldsTest.php:

<?php
class HelloWorldsTest extends \PHPUnit_Framework_TestCase {

    public function testList(){
        $c = new ContentController();
        $model = $c->getModel('helloworlds');
        $worlds = $model->getItems();
        var_dump($worlds);
        $this->assertNotEmpty($worlds);
    }
}

phpunit.xml:

<phpunit bootstrap="bootstrap.php"
    colors="true"
    convertErrorsToExceptions="true"
    convertNoticesToExceptions="true"
    convertWarningsToExceptions="true"
    processIsolation="false"
    stopOnFailure="false"
    syntaxCheck="false"
    verbose="true">
</phpunit>

二度目の試み

この回答を見た後、テストをtest / unitの下にjoomlaインストールの下に置き、phpunit.dist.xmlとbootstrap.phpをjoomla-cmsリポジトリから適切な場所にコピーしましたが、まだ

Fatal error: Class 'ContentController' not found in C:\inetpub\wwwroot\ws_cairnstest\administrator\components\com_helloworld\tests\modelsHelloWorldsTest.php on line 5

以前に受け取っていたエラー。

回答:


3

コンポーネントのテストコードを配置する場所

通常、ベストプラクティスは次のとおりです。

/src/
/tests/

しかし、/ srcをスキップし、コンポーネントディレクトリ内の/ tests /をスキップしました。フロントエンドの「abc」コンポーネントの場合、次のようになります。

/components/com_abc/
/components/com_abc/abc.php
/components/com_abc/controller.php
/components/com_abc/router.php
/components/com_abc/tests/
/components/com_abc/tests/controllerTest.php

独自のbootstrap.phpを提供する必要がありますか

やった。並べ替え。ルートのindex.phpファイルのグッズを単体テストスクリプトの先頭にコピーしました。あなたのものは私の近くにありました。次のステップは、require_once()となる別のファイルにカプセル化することです。

<?php

error_reporting(E_ALL);

define('_JEXEC', 1);
define('_PHPUNIT', 1);
define('JPATH_BASE', "/var/www/html/abcsite");

require_once JPATH_BASE . '/includes/defines.php';
require_once JPATH_BASE . '/includes/framework.php';

// Instantiate the application.
$app = JFactory::getApplication('site');

// Include dependancies
require_once '../controller.php';

// This is specific to this component
define('JPATH_COMPONENT', JPATH_BASE . "/components/com_abc");

class controllerTest extends PHPUnit_Framework_TestCase
{
    public function testCronjob()
    {

        // Need access to the controller
        $controller = JController::getInstance('Abc');

        // Should return
        $this->assertEquals('test', $controller->execute("cronjob"));

    }
...

理想的には、テストと実行方法に関する指示があるオープンソースのJoomlaコンポーネントに誰かを誘導することができます(クイックルック、最初の5つはテストがありませんでした)。

自分で転がすのは簡単だとわかりました。phpunit.xmlをセットアップすることすらしませんでした。


私はついにこれを試してみました(長い間Joomlaを使用していません!)。トリックをするようです!
魚津あほ

Error: Call to undefined method JController::getInstance()はこれを得る。
オルハーステット

6

私の答えがあなたの問題に直接対応していない場合は申し訳ありませんが、Joomlaについて話しているかどうかに関係なく、ユニットテストとは何か、それを使用する方法を理解することが重要です。あなたは多くの問題に対処してきましたが、それらすべてに対処するのはかなり困難です。

まず第一に、ドキュメント読むことが重要であるはPHPUnitを。(Joomlaとは独立して)小さなクラスを作成し、そのためのテストを作成してみてください。そのようなシナリオで最初にPHPUnitを実行します。それが何をするかを理解してください。PHPUnitを開発に役立てるのではなく、PHPUnitを実行することに集中しすぎているのではないかと思います。

Joomlaを実行するには、次のものが必要です。

  • bootstrap.php-Joomlaのインスタンスを提供します。
  • phpunit.xml-PHPUnit設定の微調整。たとえば、各コンポーネントのテストフォルダーがあるプロジェクト全体に対して1回指定する場合に便利です。そのため、一連のテストを実行できます。

表示されるエラーは可能な限り明確です。「ContentController」は明らかにJoomlaによって自動ロードされません。Joomlaのオートローダーが呼び出されたかどうか、およびクラスのロードに失敗した理由をデバッガーで確認します。最悪のシナリオでは、独自のオートローダーを提供し、ブートストラップファイルを使用して呼び出します。また、require_onceを使用して必要なファイルを手動で読み込むことも簡単な解決策です。

モックアップをテストして使用するものを決定する

提供されている例では、JModelを使用してデータベースからデータをフェッチしています。これは、TDDの観点からは不許可です。データベースからデータをフェッチできることをテストすることには、価値がありません。そこで何をテストしていますか?

データベースのデータを操作する必要がある場合は、モックを使用してデータベースからの応答をモデル化します。このようにして、テストは時間とともに一貫した動作をします。データベース内の何かを変更したからといって、テストに失敗したくはありません。

何かまたはテストする意味のある何かを計算するメソッドがある場合。これはユニットテストです。複雑なシステムから小さなユニットを取り出し、それに偽のテストデータを供給し、その動作をテストします。

システムが全体として機能することを確認する必要がある場合は、システムテストを使用します。


申し訳ありませんが、この回答はあまり意味がありません。PHPUnitを使用したことがあり、テストのポイントを理解しています。テストを実行するのに苦労しています。私の質問のテストは重要ではなく、重要な部分はそれが実行されるということです。これをより明確にするために、質問を編集しました。
うおずあほ14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.