So testen Sie eine Joomla 2.5-Komponente

12

Ich habe diese Frage auf StackOverflow gestellt und es wurde vorgeschlagen, dass ich sie hier stelle.

Ich kenne mich mit Unit- / System- / Integrationstests aus und möchte meine Joomla-Komponente testen können. Gibt es eine Standardmethode dafür?

Ich arbeite an diesem Beispiel für eine Joomla-MVC-Komponente , die keine Tests enthält. Alles, was ich in der Joomla-Dokumentation und auf verschiedenen Websites finden kann, sind Fragmente von Testcode- und bootstrap.php-Dateien. Konkret würde ich gerne wissen:

  • Speicherort des Komponententestcodes
  • Muss ich meine eigene bootstrap.php-Datei bereitstellen oder gibt es eine Möglichkeit, einfach Joomla einzuschließen und meine Tests auszuführen?

Im Idealfall könnte mich jemand an eine Open-Source-Joomla-Komponente weiterleiten, die Tests und Anweisungen zu deren Ausführung enthält (hatte einen kurzen Blick, die ersten 5 oder so hatten keine Tests).

Das nächste , was ich gefunden habe, ist das , worauf ich meinen Dummy-Test aufgebaut habe.

Was ich bisher gemacht habe

Komponentenverzeichnisstruktur:

  • Hallo Welt/
    • Administrator/
      • ...
      • Tests /
        • bootstrap.php
        • phpunit.xml
        • modelHelloWorldsTest.php
    • Seite? ˅/
      • ...
    • helloworld.xml

Erster Versuch

Um die Tests auszuführen, installiere / kopiere ich die Komponente in meine Joomla-Installation. Ich führe dann den folgenden Befehl aus ~ joomla / administration / components / com_helloworld / tests aus:

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

von dem ich empfange

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

Ich habe festgestellt, dass meine bootstrap.php nicht korrekt ist und nicht die erforderlichen Joomla-Klassen geladen hat. Ich werde dies irgendwann untersuchen, aber dies scheint eine Menge Setup zu sein, nur um einige Tests zum Laufen zu bringen.

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>

Zweiter Versuch

Nachdem ich diese Antwort gesehen habe , habe ich meine Tests unter test / unit in meiner Joomla-Installation abgelegt, phpunit.dist.xml und bootstrap.php aus dem Joomla-cms-Repo an die entsprechenden Speicherorte kopiert und trotzdem die

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

Fehler, den ich zuvor erhalten habe.

uozuAho
quelle

Antworten:

3

Speicherort des Komponententestcodes

In der Regel besagt Best Practices:

/src/
/tests/

Ich habe aber die / src übersprungen und einfach nur / tests / im Komponentenverzeichnis. Auf der Vorderseite könnte es für eine "abc" -Komponente ungefähr so ​​aussehen:

/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

Muss ich meine eigene bootstrap.php bereitstellen?

Ich tat. Art von. Ich habe gerade die Goodies in der Root-Datei index.php oben in mein Unit-Test-Skript kopiert. Ihr stand mir nahe. Mein nächster Schritt wäre, in eine separate Datei zu kapseln, die ich für _once () benötige.

<?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"));

    }
...

Im Idealfall könnte mich jemand an eine Open-Source-Joomla-Komponente weiterleiten, die Tests und Anweisungen zu deren Ausführung enthält (hatte einen kurzen Blick, die ersten 5 oder so hatten keine Tests).

Ich fand es einfach genug, meine eigenen zu rollen. Ich habe mich nicht einmal darum gekümmert, phpunit.xml einzurichten.

Ton Garot
quelle
Ich habe es endlich probiert (habe Joomla schon lange nicht mehr benutzt!). Scheint den Trick zu machen!
UozuAho
Ich bekomme Error: Call to undefined method JController::getInstance()dafür.
Olle Härstedt
6

Es tut mir leid, wenn meine Antwort Ihr Problem nicht direkt behebt, aber es ist wichtig zu verstehen, was ein Unit-Test ist und wie er verwendet wird, unabhängig davon, ob es sich um Joomla handelt oder nicht. Sie haben viele Probleme angesprochen, und es ist ziemlich schwierig, sie alle zu lösen.

Zunächst ist es wichtig, die Dokumentation auf PHPUnit zu lesen . Bauen Sie sich eine kleine Klasse (unabhängig von Joomla) und versuchen Sie, einige Tests dafür zu schreiben. Lassen Sie PHPUnit zuerst in einem solchen Szenario laufen. Verstehe, was es tut. Ich fürchte, Sie konzentrieren sich zu sehr darauf, PHPUnit zum Laufen zu bringen, anstatt zu verstehen, wie es Ihrer Entwicklung hilft.

Um Joomla zum Laufen zu bringen , benötigen Sie:

  • bootstrap.php - das gibt Ihnen eine Instanz von Joomla.
  • phpunit.xml - Feineinstellung der PHPUnit-Einstellungen. Nützlich zum Beispiel, um für ein ganzes Projekt einmal anzugeben, wo sich die Testordner in jeder Komponente befinden. Damit Sie eine Reihe von Tests durchführen können.

Der Fehler, den Sie erhalten, ist so klar wie möglich. 'ContentController' wird von Joomla offensichtlich nicht automatisch geladen. Überprüfen Sie mit einem Debugger, ob der Autoloader in Joomla aufgerufen wird und warum die Klasse nicht geladen werden kann. Im schlimmsten Fall stellen Sie Ihren eigenen Autoloader bereit und rufen Sie ihn mit der Bootstrap-Datei auf. Eine schnelle Lösung ist auch das manuelle Laden der erforderlichen Datei mit require_once.

Entscheiden Sie, was Sie testen möchten, und verwenden Sie Modelle

In dem angegebenen Beispiel verwenden Sie JModel, um Daten aus der Datenbank abzurufen. Dies ist aus TDD-Sicht ein No-Go. Das Testen, dass Sie Daten aus der Datenbank abrufen können, hat IMHO keinen Wert. Was genau testen Sie dort?

Wenn Sie mit Daten aus der Datenbank arbeiten müssen, verwenden Sie Mocks, um eine Antwort aus der Datenbank zu modellieren. Auf diese Weise werden Ihre Tests im Laufe der Zeit ein konsistentes Verhalten aufweisen. Sie möchten keine fehlgeschlagenen Tests haben, nur weil Sie etwas in der Datenbank geändert haben.

Wenn Sie eine Methode haben, die etwas oder etwas anderes berechnet, was Sinn macht, um es zu testen. Dies ist ein Unit-Test: Sie nehmen eine kleine Einheit aus Ihrem komplexen System, füttern sie mit gefälschten Testdaten und testen ihr Verhalten.

Verwenden Sie Systemtests, um sicherzustellen, dass Ihr System als Ganzes funktioniert.

Valentin Despa
quelle
Sorry, aber diese Antwort ist nicht sehr relevant. Ich habe PHPUnit schon einmal verwendet und den Sinn des Testens verstanden. Ich kämpfe nur darum, meine Tests überhaupt zum Laufen zu bringen. Der Test in meiner Frage ist nicht wichtig, der wichtige Teil ist, dass es läuft. Ich habe meine Frage in der Hoffnung bearbeitet, dies klarer zu machen.
UozuAho