Jak przetestować komponent Joomla 2.5

12

Zadałem to pytanie na StackOverflow i zasugerowano, żebym zadał je tutaj.

Znam testy jednostkowe / systemowe / integracyjne i chciałbym móc przetestować mój komponent Joomla. Czy istnieje standardowy sposób na zrobienie tego?

Pracuję nad tym przykładem komponentu joomla mvc , który nie obejmuje testów. Wszystko, co mogę znaleźć w dokumentacji Joomla i na różnych stronach internetowych, to fragmenty kodu testowego i plików bootstrap.php. W szczególności chciałbym wiedzieć:

  • Gdzie umieścić kod testu komponentu
  • Czy muszę dostarczyć własny plik bootstrap.php, czy jest jakiś sposób, aby po prostu „dołączyć Joomla” i uruchomić moje testy

Idealnie ktoś mógłby skierować mnie do komponentu Joomla o otwartym kodzie źródłowym, który ma testy i instrukcje, jak je uruchomić (rzucił okiem, pierwsze 5 lub więcej nie miało testów).

Najbliższe, jakie znalazłem, to ten , na którym oparłem swój test fikcyjny.

Co zrobiłem do tej pory

Struktura katalogów komponentów:

  • Witaj świecie/
    • Administrator/
      • ...
      • testy /
        • bootstrap.php
        • phpunit.xml
        • modelHelloWorldsTest.php
    • teren/
      • ...
    • helloworld.xml

Pierwsze podejscie

Aby uruchomić testy, instaluję / kopiuję komponent do mojej instalacji Joomla. Następnie uruchamiam następującą komendę z ~ joomla / administracja / components / com_helloworld / testy:

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

z którego otrzymuję

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

Rozumiem, że to oznacza, że ​​mój plik bootstrap.php jest niepoprawny i nie załadował niezbędnych klas Joomla. Zbadam to w pewnym momencie, ale wydaje się, że to dużo konfiguracji, aby uruchomić testy.

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';

modeleHelloWorldsTest.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>

Drugie podejście

Po zobaczeniu tej odpowiedzi poddałem testom testowanie / instalację w ramach instalacji Joomla, skopiowałem pliki phpunit.dist.xml i bootstrap.php z repozytorium joomla-cms do odpowiednich lokalizacji i nadal otrzymałem

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

błąd, który wcześniej otrzymywałam.

uozuAho
źródło

Odpowiedzi:

3

Gdzie umieścić kod testu komponentu

Zazwyczaj najlepsze praktyki mówią:

/src/
/tests/

Ale pominąłem / src i po prostu ale / testy / wewnątrz katalogu komponentów. Na froncie komponent „abc” może wyglądać mniej więcej tak:

/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

Czy muszę podać własny plik bootstrap.php

Zrobiłem. Raczej. Właśnie skopiowałem gadżety z głównego pliku index.php na początek skryptu testu jednostkowego. Wasz był blisko mojego. Moim następnym krokiem byłoby umieszczenie w osobnym pliku, który wymagałbym_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"));

    }
...

Idealnie ktoś mógłby skierować mnie do komponentu Joomla o otwartym kodzie źródłowym, który ma testy i instrukcje, jak je uruchomić (rzucił okiem, pierwsze 5 lub więcej nie miało testów).

Uznałem, że dość łatwo jest sypać własnym. Nawet nie zadałem sobie trudu, aby skonfigurować phpunit.xml.

Tone Garot
źródło
W końcu udało mi się to wypróbować (od dawna nie korzystałem z Joomla!). Wydaje się, że załatwi sprawę!
uozuAho
Rozumiem Error: Call to undefined method JController::getInstance()za to.
Olle Härstedt
6

Przepraszam, jeśli moja odpowiedź nie odnosi się bezpośrednio do twojego problemu, ale ważne jest, aby zrozumieć, czym jest testowanie jednostkowe i jak go używać, bez względu na to, czy mówimy o Joomla, czy nie. Rozwiązałeś wiele problemów i ciężko jest je rozwiązać.

Przede wszystkim ważne jest, aby przeczytać dokumentację w PHPUnit . Zbuduj sobie małą klasę (niezależnie od Joomla) i spróbuj napisać dla niej kilka testów. Uruchom PHPUnit po raz pierwszy w takim scenariuszu. Zrozum, co robi. Obawiam się, że zbytnio skupiasz się na uruchomieniu PHPUnit zamiast na zrozumieniu, w jaki sposób pomaga ci to w rozwoju.

Aby uruchomić Joomla , potrzebujesz:

  • bootstrap.php - który da ci instancję Joomla.
  • phpunit.xml - dostrajanie ustawień PHPUnit. Przydaje się na przykład do określania raz dla całego projektu, gdzie znajdują się foldery testowe w każdym komponencie. Abyś mógł uruchomić zestaw testów.

Występujący błąd jest tak wyraźny, jak to możliwe. „ContentController” najwyraźniej nie jest automatycznie ładowany przez Joomla. Sprawdź za pomocą debuggera, czy wywoływany jest autoloader w Joomla i dlaczego nie ładuje klasy. Najgorszy scenariusz to zapewnienie własnego autoloadera i wywołanie go za pomocą pliku bootstrap. Szybka poprawka polega również na ręcznym wczytaniu wymaganego pliku za pomocą requ_once.

Zdecyduj, co chcesz przetestować i użyj makiet

W podanym przykładzie używasz JModel do pobierania danych z bazy danych. Z punktu widzenia TDD jest to niemożliwe. Testowanie, czy można pobrać dane z bazy danych, nie ma wartości IMHO. Co dokładnie tam testujesz?

Jeśli potrzebujesz pracować z danymi z bazy danych, użyj próbnych modeli w celu modelowania odpowiedzi z bazy danych. W ten sposób twoje testy będą miały spójne zachowanie w czasie. Nie chcesz, aby testy zakończyły się niepowodzeniem tylko dlatego, że zmieniłeś coś w bazie danych.

Jeśli masz metodę, która oblicza coś lub cokolwiek innego, co ma sens do przetestowania. To jest testowanie jednostkowe: bierzesz małą jednostkę ze złożonego systemu, karmisz ją fałszywymi danymi testowymi i testujesz jej zachowanie.

Musisz sprawdzić, czy system działa jako całość, skorzystaj z testów systemowych.

Valentin Despa
źródło
Przepraszamy, ale ta odpowiedź nie jest zbyt istotna. Używałem wcześniej PHPUnit i rozumiem sens testowania. Po prostu staram się, aby moje testy nawet się uruchomiły. Test w moim pytaniu nie jest ważny, ważne jest to, że działa. Zredagowałem moje pytanie w nadziei, że wyjaśnię to.
uozuAho