J'ai posé cette question sur StackOverflow , et il a été suggéré de la poser ici.
Je connais bien les tests d'unité/système/d'intégration et j'aimerais pouvoir tester mon composant Joomla. Y a-t-il un moyen standard de faire cela?
Je travaille à travers cet exemple de composant joomla mvc , qui n'inclut pas les tests. Tout ce que je peux trouver dans la documentation de Joomla et sur divers sites Web, ce sont des fragments de fichiers de code de test et de fichiers bootstrap.php. Plus précisément, ce que j'aimerais savoir, c'est:
Idéalement, quelqu'un pourrait me diriger vers un composant open source de Joomla qui contient des tests et des instructions sur la façon de les exécuter (j'ai jeté un coup d'œil, les cinq premiers n'ont pas eu de tests).
Le plus proche que j'ai trouvé est this , sur lequel j'ai basé mon test factice.
Structure du répertoire du composant:
Pour exécuter les tests, j'installe/copie le composant sur mon installation Joomla. J'exécute ensuite la commande suivante depuis ~ joomla/administration/components/com_helloworld/tests:
php phpunit-4.2.phar --bootstrap bootstrap.php .
à partir de laquelle je reçois
Fatal error: Class 'ContentController' not found in C:\inetpub\wwwroot\ws_cairnstest\administrator\components\com_helloworld\tests\modelsHelloWorldsTest.php on line 5
Je suppose que cela signifie que mon bootstrap.php n’est pas correct et n’a pas chargé les classes Joomla nécessaires. J'examinerai cela à un moment donné, mais cela semble être une installation complexe juste pour faire exécuter des tests.
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>
Après avoir vu cette réponse , j’ai mis mes tests à l’essai/unité sous mon installation joomla, ai copié phpunit.dist.xml et bootstrap.php du dépôt joomla-cms à leur emplacement approprié, et j’ai quand même reçu le
Fatal error: Class 'ContentController' not found in C:\inetpub\wwwroot\ws_cairnstest\administrator\components\com_helloworld\tests\modelsHelloWorldsTest.php on line 5
erreur je recevais avant.
Où mettre le code de test des composants
Typiquement, les meilleures pratiques disent:
/src/
/tests/
Mais j'ai sauté le/src et simplement mais/tests/à l'intérieur du répertoire du composant. Sur le front-end, pour un composant "abc", cela pourrait ressembler à:
/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
Dois-je fournir mon propre fichier bootstrap.php?
J'ai fait. Sorte de. Je viens de copier les goodies dans le fichier racine index.php en haut de mon script de test unitaire. Le vôtre était proche du mien. Ma prochaine étape serait d'encapsuler dans un fichier séparé que je voudrais 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"));
}
...
Idéalement, quelqu'un pourrait me diriger vers un composant open source de Joomla qui contient des tests et des instructions sur la façon de les exécuter (j'ai jeté un coup d'œil, les cinq premiers n'ont pas eu de tests).
J'ai trouvé assez facile de rouler le mien. Je n'ai même pas pris la peine de configurer phpunit.xml.
Désolé si ma réponse ne répond pas directement à votre problème, mais il est important de comprendre ce qu'est le test unitaire et comment l'utiliser, que nous parlions de Joomla ou non. Vous avez traité de nombreuses questions et il est assez difficile de toutes les traiter.
Tout d'abord, il est important de lire la documentation sur PHPUnit . Construisez vous-même une petite classe (indépendamment de Joomla) et essayez d'écrire des tests pour la classe. Commencez par lancer PHPUnit dans un tel scénario. Comprendre ce que ça fait. Je crains que vous ne vous concentriez trop sur le lancement de PHPUnit au lieu de comprendre en quoi cela facilite votre développement.
Pour que Joomla s'exécute , vous aurez besoin de:
L'erreur que vous obtenez est aussi claire que possible. 'ContentController' n'est clairement pas chargé automatiquement par Joomla. Vérifiez avec un débogueur si l'autochargeur dans Joomla est appelé et pourquoi il ne parvient pas à charger la classe. Dans le pire des cas, fournissez votre propre autochargeur et utilisez le fichier bootstrap) pour l'appeler. Une solution rapide consiste également à charger manuellement le fichier requis avec require_once.
Décidez ce que vous voulez tester et utilisez des maquettes
Dans l'exemple fourni, vous utilisez JModel pour extraire des données de la base de données. C'est un point de vue du TDD. Test que vous pouvez extraire des données de la base de données n'a aucune valeur IMHO. Que testez-vous exactement là-bas?
Si vous devez utiliser des données de la base de données, utilisez des modèles pour modéliser une réponse de la base de données. De cette façon, vos tests auront un comportement cohérent dans le temps. Vous ne voulez pas que les tests échouent simplement parce que vous avez modifié quelque chose dans la base de données.
Si vous avez une méthode qui calcule quelque chose ou quoi que ce soit qui a du sens à tester. Il s'agit d'un test unitaire: vous prenez une petite unité de votre système complexe, vous l'alimentez avec de fausses données de test et testez son comportement.
Besoin de voir que votre système fonctionne dans son ensemble, utilisez des tests du système.