Как протестировать компонент Joomla 2.5

12

Я задал этот вопрос на StackOverflow , и мне предложили задать его здесь.

Я знаком с модульным / системным / интеграционным тестированием и хотел бы иметь возможность протестировать мой компонент Joomla. Есть ли стандартный способ сделать это?

Я работаю с этим примером компонента joomla mvc , который не включает тесты. Все, что я могу найти в документации Joomla и на различных сайтах, это фрагменты тестового кода и файлы bootstrap.php. В частности, что я хотел бы знать, это:

  • Где разместить тестовый код компонента
  • Нужно ли предоставлять свой собственный bootstrap.php, или есть какой-то способ просто «включить joomla» и запустить мои тесты

В идеале кто-то может направить меня к компоненту Joomla с открытым исходным кодом, в котором есть тесты и инструкции о том, как их запускать (был быстрый просмотр, первые 5 или около того не имели тестов).

Самое близкое, что я нашел, это то , на чем я основал свой фиктивный тест.

Что я сделал до сих пор

Структура каталогов компонентов:

  • Привет, мир/
    • админ /
      • ...
      • Тесты /
        • 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

ошибка, которую я получал раньше.

uozuAho
источник

Ответы:

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!). Кажется, чтобы сделать трюк!
uozuAho
Я получаю Error: Call to undefined method JController::getInstance()за это.
Олле Харстедт
6

Извините, если мой ответ не имеет прямого отношения к вашей проблеме, но важно понять, что такое модульное тестирование и как его использовать, независимо от того, говорим мы о Joomla или нет. Вы рассмотрели много вопросов, и со всеми из них довольно сложно разобраться.

Прежде всего, важно прочитать документацию на PHPUnit . Создайте себе небольшой класс (независимо от Joomla) и попробуйте написать несколько тестов для него. Сначала запустите PHPUnit по такому сценарию. Понять, что он делает. Боюсь, вы слишком много внимания уделяете запуску PHPUnit, а не понимаете, как это помогает вашей разработке.

Чтобы запустить Joomla , вам понадобится:

  • bootstrap.php - который даст вам экземпляр Joomla.
  • phpunit.xml - тонкая настройка параметров PHPUnit. Полезно, например, указать один раз для всего проекта, где находятся тестовые папки в каждом компоненте. Так что вы можете запустить набор тестов.

Ошибка, которую вы получаете, максимально ясна. 'ContentController' явно не загружается Joomla. Проверьте с помощью отладчика, вызван ли автозагрузчик в Joomla и почему он не может загрузить класс. В худшем случае предоставьте свой собственный автозагрузчик и используйте файл начальной загрузки для его вызова. Быстрое исправление также вручную загружает требуемый файл с помощью require_once.

Решите, что вы хотите проверить и использовать макеты

В приведенном примере вы используете JModel для извлечения данных из базы данных. Это не пойдет с точки зрения TDD. Проверка того, что вы можете получать данные из базы данных, не имеет значения ИМХО. Что именно вы там тестируете?

Если вам нужно работать с данными из базы данных, используйте mocks для моделирования ответа из базы данных. Таким образом, ваши тесты будут иметь согласованное поведение с течением времени. Вы не хотите проваливать тесты только потому, что вы что-то изменили в базе данных.

Если у вас есть метод, который вычисляет что-то или что-то еще, что имеет смысл проверить. Это модульное тестирование: вы берете небольшой блок из вашей сложной системы, кормите его поддельными данными теста и проверяете его поведение.

Нужно видеть, что ваша система работает в целом, использовать системные тесты.

Валентин Деспа
источник
Извините, но этот ответ не очень актуален. Я раньше использовал PHPUnit и понимаю смысл тестирования. Я просто изо всех сил пытаюсь заставить мои тесты даже бежать. Тест в моем вопросе не важен, важная часть в том, что он работает. Я отредактировал свой вопрос в надежде прояснить ситуацию.
uozuAho