2007-08-15 08:38:41 +02:00
|
|
|
<?php
|
2008-01-08 07:37:50 +01:00
|
|
|
/**
|
2012-04-12 08:02:46 +02:00
|
|
|
* @package framework
|
2008-01-08 07:37:50 +01:00
|
|
|
* @subpackage testing
|
|
|
|
*/
|
|
|
|
|
2007-08-15 08:38:41 +02:00
|
|
|
/**
|
Merged revisions 53150,53681,53700,53820,54200,54459 via svnmerge from
svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/roa
........
r53150 | ischommer | 2008-04-22 11:12:43 +1200 (Tue, 22 Apr 2008) | 1 line
FEATURE Added a "test mode" for /db/build which allows mock-DataObject-subclasses which are just built in a test run
........
r53681 | mrickerby | 2008-04-29 15:26:52 +1200 (Tue, 29 Apr 2008) | 1 line
adding default wrapping header and footer methods, and configurable reporting to the TestRunner
........
r53700 | mrickerby | 2008-04-29 16:41:57 +1200 (Tue, 29 Apr 2008) | 1 line
FEATURE: adding support for /dev/tests --> DevelopmentAdmin-->tests() --> TestRunner, /dev/tasks --> DevelopmentAdmin-->tasks() --> TaskRunner
........
r53820 | mrickerby | 2008-04-30 19:27:52 +1200 (Wed, 30 Apr 2008) | 1 line
BUGFIX fixing up BuildTask interface and task runner action
........
r54200 | sminnee | 2008-05-09 00:28:44 +1200 (Fri, 09 May 2008) | 1 line
Added TestSession object to help with the testing of forms
........
r54459 | sminnee | 2008-05-13 17:28:25 +1200 (Tue, 13 May 2008) | 1 line
Added a basic menu of options to /dev
........
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@54456 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-05-13 07:57:09 +02:00
|
|
|
* Controller that executes PHPUnit tests.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2010-10-19 05:43:01 +02:00
|
|
|
* Alternatively, you can also use the "phpunit" binary directly by
|
|
|
|
* pointing it to a file or folder containing unit tests.
|
|
|
|
* See phpunit.dist.xml in the webroot for configuration details.
|
2009-07-01 00:35:46 +02:00
|
|
|
*
|
|
|
|
* <h2>URL Options</h2>
|
|
|
|
* - SkipTests: A comma-separated list of test classes to skip (useful when running dev/tests/all)
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2009-07-01 00:30:33 +02:00
|
|
|
* See {@link browse()} output for generic usage instructions.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2012-04-12 08:02:46 +02:00
|
|
|
* @package framework
|
2008-01-09 05:18:36 +01:00
|
|
|
* @subpackage testing
|
2007-08-15 08:38:41 +02:00
|
|
|
*/
|
|
|
|
class TestRunner extends Controller {
|
2010-10-19 05:33:51 +02:00
|
|
|
|
Merged revisions 53150,53681,53700,53820,54200,54459 via svnmerge from
svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/roa
........
r53150 | ischommer | 2008-04-22 11:12:43 +1200 (Tue, 22 Apr 2008) | 1 line
FEATURE Added a "test mode" for /db/build which allows mock-DataObject-subclasses which are just built in a test run
........
r53681 | mrickerby | 2008-04-29 15:26:52 +1200 (Tue, 29 Apr 2008) | 1 line
adding default wrapping header and footer methods, and configurable reporting to the TestRunner
........
r53700 | mrickerby | 2008-04-29 16:41:57 +1200 (Tue, 29 Apr 2008) | 1 line
FEATURE: adding support for /dev/tests --> DevelopmentAdmin-->tests() --> TestRunner, /dev/tasks --> DevelopmentAdmin-->tasks() --> TaskRunner
........
r53820 | mrickerby | 2008-04-30 19:27:52 +1200 (Wed, 30 Apr 2008) | 1 line
BUGFIX fixing up BuildTask interface and task runner action
........
r54200 | sminnee | 2008-05-09 00:28:44 +1200 (Fri, 09 May 2008) | 1 line
Added TestSession object to help with the testing of forms
........
r54459 | sminnee | 2008-05-13 17:28:25 +1200 (Tue, 13 May 2008) | 1 line
Added a basic menu of options to /dev
........
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@54456 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-05-13 07:57:09 +02:00
|
|
|
/** @ignore */
|
|
|
|
private static $default_reporter;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $url_handlers = array(
|
2008-08-09 08:18:32 +02:00
|
|
|
'' => 'browse',
|
2010-05-25 05:22:44 +02:00
|
|
|
'coverage/module/$ModuleName' => 'coverageModule',
|
2014-05-02 13:10:18 +02:00
|
|
|
'coverage/suite/$SuiteName!' => 'coverageSuite',
|
2010-05-25 05:43:11 +02:00
|
|
|
'coverage/$TestCase!' => 'coverageOnly',
|
2010-05-25 05:22:44 +02:00
|
|
|
'coverage' => 'coverageAll',
|
2009-03-04 08:31:23 +01:00
|
|
|
'cleanupdb' => 'cleanupdb',
|
2009-07-01 00:30:33 +02:00
|
|
|
'module/$ModuleName' => 'module',
|
2014-05-02 13:10:18 +02:00
|
|
|
'suite/$SuiteName!' => 'suite',
|
2009-10-23 05:06:59 +02:00
|
|
|
'all' => 'all',
|
|
|
|
'build' => 'build',
|
2012-05-18 06:05:05 +02:00
|
|
|
'$TestCase' => 'only'
|
2008-08-09 06:06:52 +02:00
|
|
|
);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-03-21 19:48:54 +01:00
|
|
|
private static $allowed_actions = array(
|
2012-05-18 06:05:05 +02:00
|
|
|
'index',
|
|
|
|
'browse',
|
|
|
|
'coverage',
|
|
|
|
'coverageAll',
|
|
|
|
'coverageModule',
|
2014-05-02 13:10:18 +02:00
|
|
|
'coverageSuite',
|
2012-05-18 06:05:05 +02:00
|
|
|
'coverageOnly',
|
|
|
|
'cleanupdb',
|
|
|
|
'module',
|
2014-05-02 13:10:18 +02:00
|
|
|
'suite',
|
2012-05-18 06:05:05 +02:00
|
|
|
'all',
|
|
|
|
'build',
|
|
|
|
'only'
|
2011-02-13 23:14:51 +01:00
|
|
|
);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2010-10-15 05:07:08 +02:00
|
|
|
/**
|
|
|
|
* @var Array Blacklist certain directories for the coverage report.
|
|
|
|
* Filepaths are relative to the webroot, without leading slash.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2012-09-26 23:34:00 +02:00
|
|
|
* @see http://www.phpunit.de/manual/current/en/appendixes.configuration.html
|
|
|
|
* #appendixes.configuration.blacklist-whitelist
|
2010-10-15 05:07:08 +02:00
|
|
|
*/
|
|
|
|
static $coverage_filter_dirs = array(
|
2012-03-24 04:38:57 +01:00
|
|
|
'*/thirdparty',
|
|
|
|
'*/tests',
|
|
|
|
'*/lang',
|
2010-10-15 05:07:08 +02:00
|
|
|
);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
Merged revisions 53150,53681,53700,53820,54200,54459 via svnmerge from
svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/roa
........
r53150 | ischommer | 2008-04-22 11:12:43 +1200 (Tue, 22 Apr 2008) | 1 line
FEATURE Added a "test mode" for /db/build which allows mock-DataObject-subclasses which are just built in a test run
........
r53681 | mrickerby | 2008-04-29 15:26:52 +1200 (Tue, 29 Apr 2008) | 1 line
adding default wrapping header and footer methods, and configurable reporting to the TestRunner
........
r53700 | mrickerby | 2008-04-29 16:41:57 +1200 (Tue, 29 Apr 2008) | 1 line
FEATURE: adding support for /dev/tests --> DevelopmentAdmin-->tests() --> TestRunner, /dev/tasks --> DevelopmentAdmin-->tasks() --> TaskRunner
........
r53820 | mrickerby | 2008-04-30 19:27:52 +1200 (Wed, 30 Apr 2008) | 1 line
BUGFIX fixing up BuildTask interface and task runner action
........
r54200 | sminnee | 2008-05-09 00:28:44 +1200 (Fri, 09 May 2008) | 1 line
Added TestSession object to help with the testing of forms
........
r54459 | sminnee | 2008-05-13 17:28:25 +1200 (Tue, 13 May 2008) | 1 line
Added a basic menu of options to /dev
........
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@54456 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-05-13 07:57:09 +02:00
|
|
|
/**
|
|
|
|
* Override the default reporter with a custom configured subclass.
|
|
|
|
*
|
|
|
|
* @param string $reporter
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public static function set_reporter($reporter) {
|
Merged revisions 53150,53681,53700,53820,54200,54459 via svnmerge from
svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/roa
........
r53150 | ischommer | 2008-04-22 11:12:43 +1200 (Tue, 22 Apr 2008) | 1 line
FEATURE Added a "test mode" for /db/build which allows mock-DataObject-subclasses which are just built in a test run
........
r53681 | mrickerby | 2008-04-29 15:26:52 +1200 (Tue, 29 Apr 2008) | 1 line
adding default wrapping header and footer methods, and configurable reporting to the TestRunner
........
r53700 | mrickerby | 2008-04-29 16:41:57 +1200 (Tue, 29 Apr 2008) | 1 line
FEATURE: adding support for /dev/tests --> DevelopmentAdmin-->tests() --> TestRunner, /dev/tasks --> DevelopmentAdmin-->tasks() --> TaskRunner
........
r53820 | mrickerby | 2008-04-30 19:27:52 +1200 (Wed, 30 Apr 2008) | 1 line
BUGFIX fixing up BuildTask interface and task runner action
........
r54200 | sminnee | 2008-05-09 00:28:44 +1200 (Fri, 09 May 2008) | 1 line
Added TestSession object to help with the testing of forms
........
r54459 | sminnee | 2008-05-13 17:28:25 +1200 (Tue, 13 May 2008) | 1 line
Added a basic menu of options to /dev
........
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@54456 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-05-13 07:57:09 +02:00
|
|
|
if (is_string($reporter)) $reporter = new $reporter;
|
|
|
|
self::$default_reporter = $reporter;
|
|
|
|
}
|
2011-03-18 07:38:02 +01:00
|
|
|
|
|
|
|
/**
|
2011-03-24 11:30:57 +01:00
|
|
|
* Pushes a class and template manifest instance that include tests onto the
|
|
|
|
* top of the loader stacks.
|
2011-03-18 07:38:02 +01:00
|
|
|
*/
|
|
|
|
public static function use_test_manifest() {
|
2014-08-16 02:51:17 +02:00
|
|
|
$flush = true;
|
|
|
|
if(isset($_GET['flush']) && $_GET['flush'] === '0') {
|
|
|
|
$flush = false;
|
|
|
|
}
|
|
|
|
|
2012-05-28 04:25:34 +02:00
|
|
|
$classManifest = new SS_ClassManifest(
|
2014-08-16 02:51:17 +02:00
|
|
|
BASE_PATH, true, $flush
|
2012-05-28 04:25:34 +02:00
|
|
|
);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2014-05-04 03:46:06 +02:00
|
|
|
SS_ClassLoader::instance()->pushManifest($classManifest, false);
|
2012-05-28 04:25:34 +02:00
|
|
|
SapphireTest::set_test_class_manifest($classManifest);
|
2011-03-24 11:30:57 +01:00
|
|
|
|
|
|
|
SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(
|
2014-08-16 02:51:17 +02:00
|
|
|
BASE_PATH, project(), true, $flush
|
2011-03-24 11:30:57 +01:00
|
|
|
));
|
2013-02-26 04:44:48 +01:00
|
|
|
|
|
|
|
Config::inst()->pushConfigStaticManifest(new SS_ConfigStaticManifest(
|
2014-08-16 02:51:17 +02:00
|
|
|
BASE_PATH, true, $flush
|
2013-02-26 04:44:48 +01:00
|
|
|
));
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-05-27 06:39:57 +02:00
|
|
|
// Invalidate classname spec since the test manifest will now pull out new subclasses for each internal class
|
|
|
|
// (e.g. Member will now have various subclasses of DataObjects that implement TestOnly)
|
2013-06-21 00:32:08 +02:00
|
|
|
DataObject::reset();
|
2011-03-18 07:38:02 +01:00
|
|
|
}
|
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function init() {
|
Merged revisions 53150,53681,53700,53820,54200,54459 via svnmerge from
svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/roa
........
r53150 | ischommer | 2008-04-22 11:12:43 +1200 (Tue, 22 Apr 2008) | 1 line
FEATURE Added a "test mode" for /db/build which allows mock-DataObject-subclasses which are just built in a test run
........
r53681 | mrickerby | 2008-04-29 15:26:52 +1200 (Tue, 29 Apr 2008) | 1 line
adding default wrapping header and footer methods, and configurable reporting to the TestRunner
........
r53700 | mrickerby | 2008-04-29 16:41:57 +1200 (Tue, 29 Apr 2008) | 1 line
FEATURE: adding support for /dev/tests --> DevelopmentAdmin-->tests() --> TestRunner, /dev/tasks --> DevelopmentAdmin-->tasks() --> TaskRunner
........
r53820 | mrickerby | 2008-04-30 19:27:52 +1200 (Wed, 30 Apr 2008) | 1 line
BUGFIX fixing up BuildTask interface and task runner action
........
r54200 | sminnee | 2008-05-09 00:28:44 +1200 (Fri, 09 May 2008) | 1 line
Added TestSession object to help with the testing of forms
........
r54459 | sminnee | 2008-05-13 17:28:25 +1200 (Tue, 13 May 2008) | 1 line
Added a basic menu of options to /dev
........
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@54456 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-05-13 07:57:09 +02:00
|
|
|
parent::init();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-09-10 03:49:56 +02:00
|
|
|
$canAccess = (Director::isDev() || Director::is_cli() || Permission::check("ADMIN"));
|
|
|
|
if(!$canAccess) return Security::permissionFailure($this);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-13 03:47:05 +02:00
|
|
|
if (!self::$default_reporter) self::set_reporter(Director::is_cli() ? 'CliDebugView' : 'DebugView');
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2010-10-19 05:35:14 +02:00
|
|
|
if(!PhpUnitWrapper::has_php_unit()) {
|
2014-09-08 07:46:09 +02:00
|
|
|
die("Please install PHPUnit using Composer");
|
2012-07-06 12:00:38 +02:00
|
|
|
}
|
Merged revisions 53150,53681,53700,53820,54200,54459 via svnmerge from
svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/roa
........
r53150 | ischommer | 2008-04-22 11:12:43 +1200 (Tue, 22 Apr 2008) | 1 line
FEATURE Added a "test mode" for /db/build which allows mock-DataObject-subclasses which are just built in a test run
........
r53681 | mrickerby | 2008-04-29 15:26:52 +1200 (Tue, 29 Apr 2008) | 1 line
adding default wrapping header and footer methods, and configurable reporting to the TestRunner
........
r53700 | mrickerby | 2008-04-29 16:41:57 +1200 (Tue, 29 Apr 2008) | 1 line
FEATURE: adding support for /dev/tests --> DevelopmentAdmin-->tests() --> TestRunner, /dev/tasks --> DevelopmentAdmin-->tasks() --> TaskRunner
........
r53820 | mrickerby | 2008-04-30 19:27:52 +1200 (Wed, 30 Apr 2008) | 1 line
BUGFIX fixing up BuildTask interface and task runner action
........
r54200 | sminnee | 2008-05-09 00:28:44 +1200 (Fri, 09 May 2008) | 1 line
Added TestSession object to help with the testing of forms
........
r54459 | sminnee | 2008-05-13 17:28:25 +1200 (Tue, 13 May 2008) | 1 line
Added a basic menu of options to /dev
........
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@54456 467b73ca-7a2a-4603-9d3b-597d59a354a9
2008-05-13 07:57:09 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 08:40:50 +02:00
|
|
|
public function Link() {
|
|
|
|
return Controller::join_links(Director::absoluteBaseURL(), 'dev/tests/');
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2007-08-16 08:35:27 +02:00
|
|
|
/**
|
2009-10-23 05:06:59 +02:00
|
|
|
* Run test classes that should be run with every commit.
|
|
|
|
* Currently excludes PhpSyntaxTest
|
2007-08-16 08:35:27 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function all($request, $coverage = false) {
|
2011-03-18 07:38:02 +01:00
|
|
|
self::use_test_manifest();
|
2009-05-25 04:29:05 +02:00
|
|
|
$tests = ClassInfo::subclassesFor('SapphireTest');
|
|
|
|
array_shift($tests);
|
|
|
|
unset($tests['FunctionalTest']);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-10-23 05:06:59 +02:00
|
|
|
// Remove tests that don't need to be executed every time
|
|
|
|
unset($tests['PhpSyntaxTest']);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-07-01 00:35:46 +02:00
|
|
|
foreach($tests as $class => $v) {
|
|
|
|
$reflection = new ReflectionClass($class);
|
|
|
|
if(!$reflection->isInstantiable()) unset($tests[$class]);
|
|
|
|
}
|
2012-06-19 12:33:19 +02:00
|
|
|
|
2010-10-19 05:45:26 +02:00
|
|
|
$this->runTests($tests, $coverage);
|
2007-08-16 08:35:27 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-10-23 05:06:59 +02:00
|
|
|
/**
|
|
|
|
* Run test classes that should be run before build - i.e., everything possible.
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function build() {
|
2011-03-18 07:38:02 +01:00
|
|
|
self::use_test_manifest();
|
2009-10-23 05:06:59 +02:00
|
|
|
$tests = ClassInfo::subclassesFor('SapphireTest');
|
|
|
|
array_shift($tests);
|
|
|
|
unset($tests['FunctionalTest']);
|
|
|
|
foreach($tests as $class => $v) {
|
|
|
|
$reflection = new ReflectionClass($class);
|
|
|
|
if(!$reflection->isInstantiable()) unset($tests[$class]);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-10-23 05:06:59 +02:00
|
|
|
$this->runTests($tests);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 08:18:32 +02:00
|
|
|
/**
|
|
|
|
* Browse all enabled test cases in the environment
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function browse() {
|
2011-03-18 07:38:02 +01:00
|
|
|
self::use_test_manifest();
|
2008-08-09 08:40:50 +02:00
|
|
|
self::$default_reporter->writeHeader();
|
2008-11-09 16:34:29 +01:00
|
|
|
self::$default_reporter->writeInfo('Available Tests', false);
|
|
|
|
if(Director::is_cli()) {
|
|
|
|
$tests = ClassInfo::subclassesFor('SapphireTest');
|
|
|
|
$relativeLink = Director::makeRelative($this->Link());
|
|
|
|
echo "sake {$relativeLink}all: Run all " . count($tests) . " tests\n";
|
|
|
|
echo "sake {$relativeLink}coverage: Runs all tests and make test coverage report\n";
|
2009-07-01 00:30:33 +02:00
|
|
|
echo "sake {$relativeLink}module/<modulename>: Runs all tests in a module folder\n";
|
2008-11-09 16:34:29 +01:00
|
|
|
foreach ($tests as $test) {
|
|
|
|
echo "sake {$relativeLink}$test: Run $test\n";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
echo '<div class="trace">';
|
|
|
|
$tests = ClassInfo::subclassesFor('SapphireTest');
|
2008-12-04 23:38:32 +01:00
|
|
|
asort($tests);
|
2008-11-09 16:34:29 +01:00
|
|
|
echo "<h3><a href=\"" . $this->Link() . "all\">Run all " . count($tests) . " tests</a></h3>";
|
|
|
|
echo "<h3><a href=\"" . $this->Link() . "coverage\">Runs all tests and make test coverage report</a></h3>";
|
|
|
|
echo "<hr />";
|
|
|
|
foreach ($tests as $test) {
|
|
|
|
echo "<h3><a href=\"" . $this->Link() . "$test\">Run $test</a></h3>";
|
|
|
|
}
|
|
|
|
echo '</div>';
|
2008-08-09 08:18:32 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-09 08:40:50 +02:00
|
|
|
self::$default_reporter->writeFooter();
|
2008-08-09 08:18:32 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2010-05-25 05:22:44 +02:00
|
|
|
/**
|
|
|
|
* Run a coverage test across all modules
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function coverageAll($request) {
|
2011-03-18 07:38:02 +01:00
|
|
|
self::use_test_manifest();
|
2010-10-19 05:44:52 +02:00
|
|
|
$this->all($request, true);
|
2010-05-25 05:22:44 +02:00
|
|
|
}
|
2011-02-21 22:53:58 +01:00
|
|
|
|
2010-05-25 05:22:44 +02:00
|
|
|
/**
|
|
|
|
* Run only a single coverage test class or a comma-separated list of tests
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function coverageOnly($request) {
|
2010-05-25 05:22:44 +02:00
|
|
|
$this->only($request, true);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2010-05-25 05:22:44 +02:00
|
|
|
/**
|
|
|
|
* Run coverage tests for one or more "modules".
|
2012-03-24 04:38:57 +01:00
|
|
|
* A module is generally a toplevel folder, e.g. "mysite" or "framework".
|
2010-05-25 05:22:44 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function coverageModule($request) {
|
2010-05-25 05:22:44 +02:00
|
|
|
$this->module($request, true);
|
2008-05-26 08:21:30 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function cleanupdb() {
|
2009-03-04 08:31:23 +01:00
|
|
|
SapphireTest::delete_all_temp_dbs();
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2007-08-16 08:35:27 +02:00
|
|
|
/**
|
2009-03-31 21:42:08 +02:00
|
|
|
* Run only a single test class or a comma-separated list of tests
|
2007-08-16 08:35:27 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function only($request, $coverage = false) {
|
2011-03-18 07:38:02 +01:00
|
|
|
self::use_test_manifest();
|
2009-05-06 08:36:16 +02:00
|
|
|
if($request->param('TestCase') == 'all') {
|
2009-03-31 21:42:08 +02:00
|
|
|
$this->all();
|
2007-08-16 08:35:27 +02:00
|
|
|
} else {
|
2009-05-06 08:36:16 +02:00
|
|
|
$classNames = explode(',', $request->param('TestCase'));
|
2009-03-31 21:42:08 +02:00
|
|
|
foreach($classNames as $className) {
|
2009-07-17 01:56:36 +02:00
|
|
|
if(!class_exists($className) || !is_subclass_of($className, 'SapphireTest')) {
|
2012-09-26 23:34:00 +02:00
|
|
|
user_error("TestRunner::only(): Invalid TestCase '$className', cannot find matching class",
|
|
|
|
E_USER_ERROR);
|
2009-03-31 21:42:08 +02:00
|
|
|
}
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2010-05-25 05:22:44 +02:00
|
|
|
$this->runTests($classNames, $coverage);
|
2007-08-16 08:35:27 +02:00
|
|
|
}
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2009-07-01 00:30:33 +02:00
|
|
|
/**
|
|
|
|
* Run tests for one or more "modules".
|
2012-03-24 04:38:57 +01:00
|
|
|
* A module is generally a toplevel folder, e.g. "mysite" or "framework".
|
2009-07-01 00:30:33 +02:00
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function module($request, $coverage = false) {
|
2011-03-18 07:38:02 +01:00
|
|
|
self::use_test_manifest();
|
2009-07-01 00:30:33 +02:00
|
|
|
$classNames = array();
|
|
|
|
$moduleNames = explode(',', $request->param('ModuleName'));
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-06-19 12:33:19 +02:00
|
|
|
$ignored = array('functionaltest', 'phpsyntaxtest');
|
|
|
|
|
2009-07-01 00:30:33 +02:00
|
|
|
foreach($moduleNames as $moduleName) {
|
2014-05-02 13:10:18 +02:00
|
|
|
$classNames = array_merge(
|
|
|
|
$classNames,
|
|
|
|
$this->getTestsInDirectory($moduleName, $ignored)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->runTests($classNames, $coverage);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find all test classes in a directory and return an array of them.
|
|
|
|
* @param string $directory To search in
|
|
|
|
* @param array $ignore Ignore these test classes if they are found.
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function getTestsInDirectory($directory, $ignore = array()) {
|
|
|
|
$classes = ClassInfo::classes_for_folder($directory);
|
|
|
|
return $this->filterTestClasses($classes, $ignore);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find all test classes in a file and return an array of them.
|
|
|
|
* @param string $file To search in
|
|
|
|
* @param array $ignore Ignore these test classes if they are found.
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function getTestsInFile($file, $ignore = array()) {
|
|
|
|
$classes = ClassInfo::classes_for_file($file);
|
|
|
|
return $this->filterTestClasses($classes, $ignore);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $classes to search in
|
|
|
|
* @param array $ignore Ignore these test classes if they are found.
|
|
|
|
*/
|
|
|
|
protected function filterTestClasses($classes, $ignore) {
|
|
|
|
$testClasses = array();
|
|
|
|
if($classes) {
|
|
|
|
foreach($classes as $className) {
|
|
|
|
if(
|
|
|
|
class_exists($className) &&
|
|
|
|
is_subclass_of($className, 'SapphireTest') &&
|
|
|
|
!in_array($className, $ignore)
|
|
|
|
) {
|
|
|
|
$testClasses[] = $className;
|
2009-07-02 02:17:29 +02:00
|
|
|
}
|
2009-07-01 00:30:33 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-02 13:10:18 +02:00
|
|
|
return $testClasses;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run tests for a test suite defined in phpunit.xml
|
|
|
|
*/
|
|
|
|
public function suite($request, $coverage = false) {
|
|
|
|
self::use_test_manifest();
|
|
|
|
$suite = $request->param('SuiteName');
|
|
|
|
$xmlFile = BASE_PATH.'/phpunit.xml';
|
|
|
|
if(!is_readable($xmlFile)) {
|
|
|
|
user_error("TestRunner::suite(): $xmlFile is not readable", E_USER_ERROR);
|
|
|
|
}
|
|
|
|
$xml = simplexml_load_file($xmlFile);
|
|
|
|
$suite = $xml->xpath("//phpunit/testsuite[@name='$suite']");
|
|
|
|
if(empty($suite)) {
|
|
|
|
user_error("TestRunner::suite(): couldn't find the $suite testsuite in phpunit.xml");
|
|
|
|
}
|
|
|
|
$suite = array_shift($suite);
|
|
|
|
$classNames = array();
|
|
|
|
if(isset($suite->directory)) {
|
|
|
|
foreach($suite->directory as $directory) {
|
|
|
|
$classNames = array_merge($classNames, $this->getTestsInDirectory($directory));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(isset($suite->file)) {
|
|
|
|
foreach($suite->file as $file) {
|
|
|
|
$classNames = array_merge($classNames, $this->getTestsInFile($file));
|
|
|
|
}
|
|
|
|
}
|
2012-06-19 12:33:19 +02:00
|
|
|
|
2010-05-25 05:22:44 +02:00
|
|
|
$this->runTests($classNames, $coverage);
|
2009-07-01 00:30:33 +02:00
|
|
|
}
|
2007-08-16 08:35:27 +02:00
|
|
|
|
2014-05-02 13:10:18 +02:00
|
|
|
/**
|
|
|
|
* Give us some sweet code coverage reports for a particular suite.
|
|
|
|
*/
|
|
|
|
public function coverageSuite($request) {
|
|
|
|
return $this->suite($request, true);
|
|
|
|
}
|
|
|
|
|
2009-07-01 00:35:46 +02:00
|
|
|
/**
|
|
|
|
* @param array $classList
|
|
|
|
* @param boolean $coverage
|
|
|
|
*/
|
2012-09-19 12:07:39 +02:00
|
|
|
public function runTests($classList, $coverage = false) {
|
2009-08-21 05:02:43 +02:00
|
|
|
$startTime = microtime(true);
|
2012-04-18 13:11:53 +02:00
|
|
|
|
|
|
|
// disable xdebug, as it messes up test execution
|
2009-03-04 04:44:11 +01:00
|
|
|
if(function_exists('xdebug_disable')) xdebug_disable();
|
2012-04-18 13:11:53 +02:00
|
|
|
|
|
|
|
ini_set('max_execution_time', 0);
|
|
|
|
|
2008-08-13 04:47:14 +02:00
|
|
|
$this->setUp();
|
2012-04-18 13:11:53 +02:00
|
|
|
|
2009-07-01 00:35:46 +02:00
|
|
|
// Optionally skip certain tests
|
|
|
|
$skipTests = array();
|
2015-04-30 01:04:08 +02:00
|
|
|
if($this->getRequest()->getVar('SkipTests')) {
|
|
|
|
$skipTests = explode(',', $this->getRequest()->getVar('SkipTests'));
|
2009-07-01 00:35:46 +02:00
|
|
|
}
|
2012-04-18 13:11:53 +02:00
|
|
|
|
2013-06-03 22:25:08 +02:00
|
|
|
$abstractClasses = array();
|
|
|
|
foreach($classList as $className) {
|
|
|
|
// Ensure that the autoloader pulls in the test class, as PHPUnit won't know how to do this.
|
|
|
|
class_exists($className);
|
|
|
|
$reflection = new ReflectionClass($className);
|
|
|
|
if ($reflection->isAbstract()) {
|
|
|
|
array_push($abstractClasses, $className);
|
|
|
|
}
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2013-06-03 22:25:08 +02:00
|
|
|
$classList = array_diff($classList, $skipTests, $abstractClasses);
|
|
|
|
|
2008-08-11 01:03:35 +02:00
|
|
|
// run tests before outputting anything to the client
|
2007-08-15 08:38:41 +02:00
|
|
|
$suite = new PHPUnit_Framework_TestSuite();
|
2009-05-01 01:52:55 +02:00
|
|
|
natcasesort($classList);
|
2007-08-16 08:35:27 +02:00
|
|
|
foreach($classList as $className) {
|
2008-01-08 03:12:18 +01:00
|
|
|
// Ensure that the autoloader pulls in the test class, as PHPUnit won't know how to do this.
|
|
|
|
class_exists($className);
|
2009-04-22 05:22:09 +02:00
|
|
|
$suite->addTest(new SapphireTestSuite($className));
|
2007-08-15 08:38:41 +02:00
|
|
|
}
|
2008-08-11 08:10:59 +02:00
|
|
|
|
|
|
|
// Remove the error handler so that PHPUnit can add its own
|
|
|
|
restore_error_handler();
|
|
|
|
|
2012-03-24 04:38:57 +01:00
|
|
|
self::$default_reporter->writeHeader("SilverStripe Test Runner");
|
2012-04-18 13:11:53 +02:00
|
|
|
if (count($classList) > 1) {
|
2009-12-16 06:38:42 +01:00
|
|
|
self::$default_reporter->writeInfo("All Tests", "Running test cases: ",implode(", ", $classList));
|
2012-04-18 13:11:53 +02:00
|
|
|
} elseif (count($classList) == 1) {
|
2014-08-14 02:24:56 +02:00
|
|
|
self::$default_reporter->writeInfo(reset($classList), '');
|
2010-10-19 05:33:51 +02:00
|
|
|
} else {
|
2012-04-18 13:11:53 +02:00
|
|
|
// border case: no tests are available.
|
|
|
|
self::$default_reporter->writeInfo('', '');
|
2008-08-13 03:47:05 +02:00
|
|
|
}
|
2008-08-09 08:18:32 +02:00
|
|
|
|
2010-10-19 05:33:51 +02:00
|
|
|
// perform unit tests (use PhpUnitWrapper or derived versions)
|
2010-10-19 05:35:14 +02:00
|
|
|
$phpunitwrapper = PhpUnitWrapper::inst();
|
2010-10-19 05:33:51 +02:00
|
|
|
$phpunitwrapper->setSuite($suite);
|
|
|
|
$phpunitwrapper->setCoverageStatus($coverage);
|
2008-08-25 03:41:58 +02:00
|
|
|
|
2012-10-26 22:54:08 +02:00
|
|
|
// Make sure TearDown is called (even in the case of a fatal error)
|
|
|
|
$self = $this;
|
|
|
|
register_shutdown_function(function() use ($self) {
|
|
|
|
$self->tearDown();
|
|
|
|
});
|
|
|
|
|
2010-10-19 05:33:51 +02:00
|
|
|
$phpunitwrapper->runTests();
|
|
|
|
|
|
|
|
// get results of the PhpUnitWrapper class
|
|
|
|
$reporter = $phpunitwrapper->getReporter();
|
|
|
|
$results = $phpunitwrapper->getFrameworkTestResults();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-09-23 05:22:13 +02:00
|
|
|
if(!Director::is_cli()) echo '<div class="trace">';
|
2008-08-09 08:18:32 +02:00
|
|
|
$reporter->writeResults();
|
2009-08-21 05:02:43 +02:00
|
|
|
|
|
|
|
$endTime = microtime(true);
|
|
|
|
if(Director::is_cli()) echo "\n\nTotal time: " . round($endTime-$startTime,3) . " seconds\n";
|
2012-09-01 01:58:52 +02:00
|
|
|
else echo "<p class=\"total-time\">Total time: " . round($endTime-$startTime,3) . " seconds</p>\n";
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-05-15 10:46:40 +02:00
|
|
|
if(!Director::is_cli()) echo '</div>';
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-05-15 06:58:13 +02:00
|
|
|
// Put the error handlers back
|
2015-09-04 05:50:54 +02:00
|
|
|
$errorHandler = Injector::inst()->get('ErrorHandler');
|
|
|
|
$errorHandler->start();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-05-15 10:46:40 +02:00
|
|
|
if(!Director::is_cli()) self::$default_reporter->writeFooter();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-08-13 04:47:14 +02:00
|
|
|
$this->tearDown();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2008-05-15 10:46:40 +02:00
|
|
|
// Todo: we should figure out how to pass this data back through Director more cleanly
|
2008-08-13 03:47:05 +02:00
|
|
|
if(Director::is_cli() && ($results->failureCount() + $results->errorCount()) > 0) exit(2);
|
2007-08-15 12:01:35 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function setUp() {
|
2009-11-27 01:24:56 +01:00
|
|
|
// The first DB test will sort out the DB, we don't have to
|
2008-10-16 21:48:12 +02:00
|
|
|
SSViewer::flush_template_cache();
|
2008-08-13 04:47:14 +02:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2012-09-19 12:07:39 +02:00
|
|
|
public function tearDown() {
|
2008-08-13 04:47:14 +02:00
|
|
|
SapphireTest::kill_temp_db();
|
|
|
|
}
|
2007-08-15 12:01:35 +02:00
|
|
|
}
|