testsuite.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: testsuite.php 8163 2009-04-30 23:38:14Z mark_story $ */
00003 /**
00004  * Test Suite Shell
00005  *
00006  * This Shell allows the running of test suites via the cake command line
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  *  Licensed under The Open Group Test Suite License
00014  *  Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
00019  * @package       cake
00020  * @subpackage    cake.cake.console.libs
00021  * @since         CakePHP(tm) v 1.2.0.4433
00022  * @version       $Revision: 8163 $
00023  * @modifiedby    $LastChangedBy: mark_story $
00024  * @lastmodified  $Date: 2009-04-30 19:38:14 -0400 (Thu, 30 Apr 2009) $
00025  * @license       http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
00026  */
00027 class TestSuiteShell extends Shell {
00028 /**
00029  * The test category, "app", "core" or the name of a plugin
00030  *
00031  * @var string
00032  * @access public
00033  */
00034     var $category = '';
00035 /**
00036  * "group", "case" or "all"
00037  *
00038  * @var string
00039  * @access public
00040  */
00041     var $type = '';
00042 /**
00043  * Path to the test case/group file
00044  *
00045  * @var string
00046  * @access public
00047  */
00048     var $file = '';
00049 /**
00050  * Storage for plugins that have tests
00051  *
00052  * @var string
00053  * @access public
00054  */
00055     var $plugins = array();
00056 /**
00057  * Convenience variable to avoid duplicated code
00058  *
00059  * @var string
00060  * @access public
00061  */
00062     var $isPluginTest = false;
00063 /**
00064  * Stores if the user wishes to get a code coverage analysis report
00065  *
00066  * @var string
00067  * @access public
00068  */
00069     var $doCoverage = false;
00070 /**
00071  * The headline for the test output
00072  *
00073  * @var string
00074  * @access public
00075  */
00076     var $headline = 'CakePHP Test Shell';
00077 /**
00078  * Initialization method installs Simpletest and loads all plugins
00079  *
00080  * @return void
00081  * @access public
00082  */
00083     function initialize() {
00084         $corePath = Configure::corePaths('cake');
00085         if (isset($corePath[0])) {
00086             define('TEST_CAKE_CORE_INCLUDE_PATH', rtrim($corePath[0], DS) . DS);
00087         } else {
00088             define('TEST_CAKE_CORE_INCLUDE_PATH', CAKE_CORE_INCLUDE_PATH);
00089         }
00090 
00091         $this->__installSimpleTest();
00092 
00093         require_once CAKE . 'tests' . DS . 'lib' . DS . 'test_manager.php';
00094         require_once CAKE . 'tests' . DS . 'lib' . DS . 'cli_reporter.php';
00095 
00096         $plugins = Configure::listObjects('plugin');
00097         foreach ($plugins as $p) {
00098             $this->plugins[] = Inflector::underscore($p);
00099         }
00100     }
00101 /**
00102  * Main entry point to this shell
00103  *
00104  * @return void
00105  * @access public
00106  */
00107     function main() {
00108         $this->out($this->headline);
00109         $this->hr();
00110 
00111         if (count($this->args) > 0) {
00112             $this->category = $this->args[0];
00113 
00114             if (!in_array($this->category, array('app', 'core'))) {
00115                 $this->isPluginTest = true;
00116             }
00117 
00118             if (isset($this->args[1])) {
00119                 $this->type = $this->args[1];
00120             }
00121 
00122             if (isset($this->args[2])) {
00123                 if ($this->args[2] == 'cov') {
00124                     $this->doCoverage = true;
00125                 } else {
00126                     $this->file = Inflector::underscore($this->args[2]);
00127                 }
00128             }
00129 
00130             if (isset($this->args[3]) && $this->args[3] == 'cov') {
00131                 $this->doCoverage = true;
00132             }
00133         } else {
00134             $this->err('Sorry, you did not pass any arguments!');
00135         }
00136 
00137         if ($this->__canRun()) {
00138             $this->out('Running '.$this->category.' '.$this->type.' '.$this->file);
00139 
00140             $exitCode = 0;
00141             if (!$this->__run()) {
00142                 $exitCode = 1;
00143             }
00144             exit($exitCode);
00145         } else {
00146             $this->err('Sorry, the tests could not be found.');
00147             exit(1);
00148         }
00149     }
00150 /**
00151  * Help screen
00152  *
00153  * @return void
00154  * @access public
00155  */
00156     function help() {
00157         $this->out('Usage: ');
00158         $this->out("\tcake testsuite category test_type file");
00159         $this->out("\t\t- category - \"app\", \"core\" or name of a plugin");
00160         $this->out("\t\t- test_type - \"case\", \"group\" or \"all\"");
00161         $this->out("\t\t- test_file - file name with folder prefix and without the (test|group).php suffix");
00162         $this->out('');
00163         $this->out('Examples: ');
00164         $this->out("\t\tcake testsuite app all");
00165         $this->out("\t\tcake testsuite core all");
00166         $this->out('');
00167         $this->out("\t\tcake testsuite app case behaviors/debuggable");
00168         $this->out("\t\tcake testsuite app case models/my_model");
00169         $this->out("\t\tcake testsuite app case controllers/my_controller");
00170         $this->out('');
00171         $this->out("\t\tcake testsuite core case file");
00172         $this->out("\t\tcake testsuite core case router");
00173         $this->out("\t\tcake testsuite core case set");
00174         $this->out('');
00175         $this->out("\t\tcake testsuite app group mygroup");
00176         $this->out("\t\tcake testsuite core group acl");
00177         $this->out("\t\tcake testsuite core group socket");
00178         $this->out('');
00179         $this->out("\t\tcake testsuite bugs case models/bug");
00180         $this->out("\t\t  // for the plugin 'bugs' and its test case 'models/bug'");
00181         $this->out("\t\tcake testsuite bugs group bug");
00182         $this->out("\t\t  // for the plugin bugs and its test group 'bug'");
00183         $this->out('');
00184         $this->out('Code Coverage Analysis: ');
00185         $this->out("\n\nAppend 'cov' to any of the above in order to enable code coverage analysis");
00186     }
00187 /**
00188  * Checks if the arguments supplied point to a valid test file and thus the shell can be run.
00189  *
00190  * @return bool true if it's a valid test file, false otherwise
00191  * @access private
00192  */
00193     function __canRun() {
00194         $isNeitherAppNorCore = !in_array($this->category, array('app', 'core'));
00195         $isPlugin = in_array(Inflector::underscore($this->category), $this->plugins);
00196 
00197         if ($isNeitherAppNorCore && !$isPlugin) {
00198             $this->err($this->category.' is an invalid test category (either "app", "core" or name of a plugin)');
00199             return false;
00200         }
00201 
00202         $folder = $this->__findFolderByCategory($this->category);
00203         if (!file_exists($folder)) {
00204             $this->err($folder . ' not found');
00205             return false;
00206         }
00207 
00208         if (!in_array($this->type, array('all', 'group', 'case'))) {
00209             $this->err($this->type.' is invalid. Should be case, group or all');
00210             return false;
00211         }
00212 
00213         switch ($this->type) {
00214             case 'all':
00215                 return true;
00216                 break;
00217             case 'group':
00218                 if (file_exists($folder.DS.'groups'.DS.$this->file.'.group.php')) {
00219                     return true;
00220                 }
00221                 break;
00222             case 'case':
00223                 if ($this->category == 'app' && file_exists($folder.DS.'cases'.DS.$this->file.'.test.php')) {
00224                     return true;
00225                 }
00226 
00227                 if ($this->category == 'core' && file_exists($folder.DS.'cases'.DS.'libs'.DS.$this->file.'.test.php')) {
00228                     return true;
00229                 }
00230 
00231                 if ($isPlugin && file_exists($folder.DS.'cases'.DS.$this->file.'.test.php')) {
00232                     return true;
00233                 }
00234                 break;
00235         }
00236 
00237         $this->err($this->category.' '.$this->type.' '.$this->file.' is an invalid test identifier');
00238         return false;
00239     }
00240 /**
00241  * Executes the tests depending on our settings
00242  *
00243  * @return void
00244  * @access private
00245  */
00246     function __run() {
00247         $reporter = new CLIReporter();
00248         $this->__setGetVars();
00249 
00250         if ($this->type == 'all') {
00251             return TestManager::runAllTests($reporter);
00252         }
00253 
00254         if ($this->doCoverage) {
00255             if (!extension_loaded('xdebug')) {
00256                 $this->out('You must install Xdebug to use the CakePHP(tm) Code Coverage Analyzation. Download it from http://www.xdebug.org/docs/install');
00257                 exit(0);
00258             }
00259         }
00260 
00261         if ($this->type == 'group') {
00262             $ucFirstGroup = ucfirst($this->file);
00263 
00264             $path = CORE_TEST_GROUPS;
00265             if ($this->category == 'app') {
00266                 $path = APP_TEST_GROUPS;
00267             } elseif ($this->isPluginTest) {
00268                 $path = APP.'plugins'.DS.$this->category.DS.'tests'.DS.'groups';
00269             }
00270 
00271             if ($this->doCoverage) {
00272                 require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php';
00273                 CodeCoverageManager::start($ucFirstGroup, $reporter);
00274             }
00275             $result = TestManager::runGroupTest($ucFirstGroup, $reporter);
00276             if ($this->doCoverage) {
00277                 CodeCoverageManager::report();
00278             }
00279             return $result;
00280         }
00281 
00282         $case = 'libs'.DS.$this->file.'.test.php';
00283         if ($this->category == 'app') {
00284             $case = $this->file.'.test.php';
00285         } elseif ($this->isPluginTest) {
00286             $case = $this->file.'.test.php';
00287         }
00288 
00289         if ($this->doCoverage) {
00290             require_once CAKE . 'tests' . DS . 'lib' . DS . 'code_coverage_manager.php';
00291             CodeCoverageManager::start($case, $reporter);
00292         }
00293 
00294         $result = TestManager::runTestCase($case, $reporter);
00295         if ($this->doCoverage) {
00296             CodeCoverageManager::report();
00297         }
00298 
00299         return $result;
00300     }
00301 /**
00302  * Finds the correct folder to look for tests for based on the input category
00303  *
00304  * @return string the folder path
00305  * @access private
00306  */
00307     function __findFolderByCategory($category) {
00308         $folder = '';
00309         $paths = array(
00310             'core' => CAKE,
00311             'app'  => APP
00312         );
00313 
00314         if (array_key_exists($category, $paths)) {
00315             $folder = $paths[$category] . 'tests';
00316         } else {
00317             $scoredCategory = Inflector::underscore($category);
00318             $folder = APP . 'plugins' . DS . $scoredCategory . DS;
00319             $pluginPaths = Configure::read('pluginPaths');
00320             foreach ($pluginPaths as $path) {
00321                 if (file_exists($path . $scoredCategory . DS . 'tests')) {
00322                     $folder = $path . $scoredCategory . DS . 'tests';
00323                     break;
00324                 }
00325             }
00326         }
00327         return $folder;
00328     }
00329 /**
00330  * Sets some get vars needed for TestManager
00331  *
00332  * @return void
00333  * @access private
00334  */
00335     function __setGetVars() {
00336         if (in_array($this->category, $this->plugins)) {
00337             $_GET['plugin'] = $this->category;
00338         } elseif (in_array(Inflector::Humanize($this->category), $this->plugins)) {
00339             $_GET['plugin'] = Inflector::Humanize($this->category);
00340         } elseif ($this->category == 'app') {
00341             $_GET['app'] = true;
00342         }
00343         if ($this->type == 'group') {
00344             $_GET['group'] = true;
00345         }
00346     }
00347 /**
00348  * tries to install simpletest and exits gracefully if it is not there
00349  *
00350  * @return void
00351  * @access private
00352  */
00353     function __installSimpleTest() {
00354         if (!App::import('Vendor', 'simpletest' . DS . 'reporter')) {
00355             $this->err('Sorry, Simpletest could not be found. Download it from http://simpletest.org and install it to your vendors directory.');
00356             exit;
00357         }
00358     }
00359 }
00360 ?>

Generated on Sun Nov 22 00:30:52 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7