如何测试Joomla 2.5组件


12

我在StackOverflow上问了这个问题,有人建议我在这里问。

我熟悉单元/系统/集成测试,并且希望能够测试我的Joomla组件。有这样做的标准方法吗?

我正在研究这个joomla mvc组件示例,其中不包含测试。我在Joomla文档和各个网站上都能找到的只是测试代码和bootstrap.php文件的片段。我特别想知道的是:

  • 组件测试代码放在哪里
  • 我是否需要提供自己的bootstrap.php,还是有某种方法可以仅“包括joomla”并运行测试

理想情况下,有人可以将我定向到一个开放源代码的Joomla组件,该组件具有有关如何运行它们的测试和说明(快速浏览,前5个左右没有测试)。

我找到的最接近的是this,它基于我的虚拟测试。

到目前为止我做了什么

组件目录结构:

  • 你好,世界/
    • 管理员/
      • ...
      • 测试/
        • 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>

第二次尝试

看到此答案后,我将测试放在我的joomla安装下的test / unit下,将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

我之前收到的错误。

Answers:


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 2015年

我得到Error: Call to undefined method JController::getInstance()这个。
OlleHärstedt17年

6

抱歉,如果我的回答没有直接解决您的问题,但是无论我们是否在谈论Joomla,了解任何单元测试以及如何使用它都是很重要的。您已经解决了很多问题,要解决所有问题都相当困难。

首先,它读取的文档是很重要PHPUnit的。为自己建立一个小类(独立于Joomla),并尝试为此编写一些测试。在这种情况下,首先使PHPUnit运行。了解它的作用。恐怕您过于关注使PHPUnit运行,而不是了解它如何帮助您的开发。

要使Joomla运行,您需要:

  • bootstrap.php-将为您提供Joomla的实例。
  • phpunit.xml-微调PHPUnit设置。例如,对于整个项目一次指定每个组件中的测试文件夹在哪里很有用。这样您就可以运行一套测试。

您得到的错误是尽可能清楚的。Joomla显然不会自动加载“ ContentController”。检查调试器是否调用了Joomla中的自动加载器,以及为什么它无法加载该类。最坏的情况是提供您自己的自动加载器,并使用引导程序文件来调用它。一个快速修复方法是使用require_once手动加载所需的文件。

确定要测试和使用的模型

在提供的示例中,您正在使用JModel从数据库中获取数据。从TDD的角度来看,这是不可行的。测试可以从数据库中获取数据的测试没有价值恕我直言。您在那里到底要测试什么?

如果需要使用数据库中的数据,请使用模拟对数据库的响应进行建模。这样,随着时间的推移,您的测试将具有一致的行为。您不希望仅因为您更改了数据库中的某些内容而导致测试失败。

如果您有一种方法可以计算某些东西或其他需要测试的东西。这是单元测试:您从复杂的系统中取出一小块单元,向其提供虚假的测试数据并测试其行为。

需要查看您的系统是否可以正常运行,请使用系统测试。


抱歉,这个答案不是很相关。我以前使用过PHPUnit,并且了解测试的要点。我只是在努力使测试无法运行。我的问题中的测试并不重要,重要的是它可以运行。我已经编辑了我的问题,希望使这一点更加清楚。
uozuAho 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.