Como testar um componente Joomla 2.5

12

Eu fiz essa pergunta no StackOverflow e foi sugerido que eu faça aqui.

Estou familiarizado com os testes de unidade / sistema / integração e gostaria de poder testar meu componente Joomla. Existe uma maneira padrão de fazer isso?

Estou trabalhando neste exemplo de componente do joomla mvc , que não inclui testes. Tudo o que posso encontrar na documentação do Joomla e em vários sites são fragmentos de código de teste e arquivos bootstrap.php. Especificamente, o que eu gostaria de saber é:

  • Onde colocar o código de teste do componente
  • Preciso fornecer meu próprio bootstrap.php ou existe alguma maneira de apenas 'incluir o joomla' e executar meus testes

Idealmente, alguém poderia me direcionar para um componente Joomla de código aberto que possui testes e instruções sobre como executá-los (deu uma olhada rápida, os primeiros 5 ou mais não tinham testes).

O mais próximo que encontrei é esse , no qual baseei meu teste fictício.

O que eu fiz até agora

Estrutura do diretório de componentes:

  • Olá Mundo/
    • admin /
      • ...
      • testes /
        • bootstrap.php
        • phpunit.xml
        • modelHelloWorldsTest.php
    • local/
      • ...
    • helloworld.xml

Primeira tentativa

Para executar os testes, eu instalo / copio o componente na minha instalação do Joomla. Em seguida, executo o seguinte comando em ~ joomla / Administration / components / com_helloworld / tests:

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

do qual eu recebo

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

Eu entendo que isso significa que meu bootstrap.php não está correto e não carregou as classes necessárias do Joomla. Vou investigar isso em algum momento, mas isso parece muita configuração apenas para que alguns testes sejam executados.

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>

Segunda tentativa

Depois de ver esta resposta , coloquei meus testes em test / unit em minha instalação do joomla, copiei phpunit.dist.xml e bootstrap.php do repositório joomla-cms para seus locais apropriados e ainda obtive o

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

erro que eu estava recebendo antes.

uozuAho
fonte

Respostas:

3

Onde colocar o código de teste do componente

Normalmente, as melhores práticas dizem:

/src/
/tests/

Mas pulei o / src e simplesmente but / tests / dentro do diretório do componente. No front-end, para um componente "abc", pode ser algo como:

/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

Preciso fornecer meu próprio bootstrap.php

Eu fiz. Tipo de. Acabei de copiar as guloseimas no arquivo index.php raiz para a parte superior do meu script de teste de unidade. O seu estava perto do meu. Meu próximo passo seria encapsular em um arquivo separado que eu exigiria_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"));

    }
...

Idealmente, alguém poderia me direcionar para um componente Joomla de código aberto que possui testes e instruções sobre como executá-los (deu uma olhada rápida, os primeiros 5 ou mais não tinham testes).

Achei fácil o suficiente para fazer o meu próprio. Eu nem me preocupei em configurar o phpunit.xml.

Tom Garot
fonte
Eu finalmente tentei fazer isso (não usei o Joomla há muito tempo!). Parece fazer o truque!
UzuAho
Eu entendo Error: Call to undefined method JController::getInstance()isso.
Olle Härstedt 14/02
6

Desculpe se a minha resposta não aborda diretamente o seu problema, mas é importante entender o que é o teste de unidade e como usá-lo, não importa se estamos falando sobre o Joomla ou não. Você abordou muitos problemas e é bastante difícil lidar com todos eles.

Antes de tudo, é importante ler a documentação no PHPUnit . Crie uma classe pequena (independentemente do Joomla) e tente escrever alguns testes para ele. Faça com que o PHPUnit seja executado pela primeira vez nesse cenário. Entenda o que ele faz. Receio que você esteja se concentrando demais na execução do PHPUnit em vez de entender como isso ajuda no seu desenvolvimento.

Para executar o Joomla , você precisará de:

  • bootstrap.php - que fornecerá uma instância do Joomla.
  • phpunit.xml - ajustando as configurações do PHPUnit. Útil, por exemplo, para especificar uma vez para um projeto inteiro onde estão as pastas de teste em cada componente. Para que você possa executar um conjunto de testes.

O erro que você está recebendo é o mais claro possível. O 'ContentController' claramente não é carregado automaticamente pelo Joomla. Verifique com um depurador se o carregador automático no Joomla é chamado e por que ele falha ao carregar a classe. No pior cenário, forneça seu próprio carregador automático e use o arquivo de inicialização para chamá-lo. Uma solução rápida também está carregando manualmente o arquivo necessário com require_once.

Decida o que você deseja testar e usar modelos

No exemplo fornecido, você está usando o JModel para buscar dados do banco de dados. Este é um impedimento do ponto de vista do TDD. Testar que você pode buscar dados do banco de dados não tem valor IMHO. O que exatamente você está testando lá?

Se você precisar trabalhar com dados do banco de dados, use zombarias para modelar uma resposta do banco de dados. Dessa forma, seus testes terão um comportamento consistente ao longo do tempo. Você não deseja ter falhas nos testes apenas porque alterou algo no banco de dados.

Se você possui um método que calcula algumas coisas ou qualquer outra coisa que tenha sentido em testar. Este é um teste de unidade: você pega uma pequena unidade do seu sistema complexo, alimenta-a com dados de teste falsos e testa seu comportamento.

Precisa verificar se o seu sistema funciona como um todo, use testes do sistema.

Valentin Despa
fonte
Desculpe, mas esta resposta não é muito relevante. Eu usei o PHPUnit antes e entendo o ponto de teste. Estou apenas lutando para que meus testes sejam executados. O teste na minha pergunta não é importante, a parte importante é que ele seja executado. Eu editei minha pergunta na esperança de deixar isso mais claro.
uozuAho