refactored test runner a bit

This commit is contained in:
tmont 2009-06-20 03:35:46 +00:00
parent 2b64eeb21f
commit c4bcc9082b
5 changed files with 129 additions and 47 deletions

View File

@ -0,0 +1,88 @@
<?php
abstract class BaseTestRunner {
protected $tests;
protected $listeners;
protected $options;
public function __construct(array $tests = array(), array $listeners = array(), array $options = array()) {
$this->tests = $tests;
$this->listeners = $listeners;
$this->options = (!empty($options)) ? $this->parseOptions($options) : array();
}
public final function warn($message) {
foreach ($this->listeners as $listener) {
$listener->onFrameworkWarning($message);
}
}
public final function error($message) {
foreach ($this->listeners as $listener) {
$listener->onFrameworkError($message);
}
}
public final function addTest(Testable $test) {
$this->tests[] = $test;
return $this;
}
public final function addListener(TestListener $listener) {
$this->listeners[] = $listener;
return $this;
}
public final function setOptions(array $options) {
$this->options = $this->parseOptions($options);
return $this;
}
protected final function parseOptions(array $unparsed) {
$allowedOptions = $this->getAllowableOptions();
$options = array_fill_keys(array_key($allowedOptions), null);
foreach ($unparsed as $option => $value) {
if (!isset($allowedOptions[$option])) {
throw new InvalidOptionException($option);
}
if (gettype($value) !== $allowedOptions[$option]) {
throw new InvalidOptionException($option, 'Expected a value of type ' . $allowedOptions[$option] . ', got ' . gettype($value));
}
$options[$option] = $value;
}
return $options;
}
public function runTests() {
$results = array();
foreach ($this->tests as $test) {
if ($test instanceof Testable) {
try {
$results[] = $test->run($this->listeners);
} catch (TUnitException $e) {
$this->error($e->getMessage());
}
} else {
$this->warn('Unable to run test because it is not an instance of Testable (' . gettype($test) . ')');
}
}
return $results;
}
public function publishResults(array $testResults) {
foreach ($this->listeners as $listener) {
$listener->publishTestResults($testResults);
}
}
public abstract function run();
protected abstract function getAllowableOptions();
}
?>

View File

@ -1,51 +1,19 @@
<?php <?php
class TestRunner { class ConsoleTestRunner extends BaseTestRunner {
protected $tests;
protected $listeners;
public function __construct(array $tests = array(), array $listeners = array()) {
$this->tests = $tests;
$this->listeners = $listeners;
}
public final function addTest(Testable $test) {
$this->tests[] = $test;
return $this;
}
public final function addListener(TestListener $listener) {
$this->listeners[] = $listener;
return $this;
}
public function runTests() {
$results = array();
foreach ($this->tests as $test) {
if ($test instanceof Testable) {
$results[] = $test->run($this->listeners);
} else {
foreach ($this->listeners as $listener) {
$listener->onFrameworkWarning('Unable to run test because it is not an instance of Testable (' . gettype($test) . ')');
}
}
}
return $results;
}
public function publishResults(array $testResults) {
foreach ($this->listeners as $listener) {
$listener->publishTestResults($testResults);
}
}
public function run() { public function run() {
self::printMeta(); self::printMeta();
$this->publishResults($this->runTests()); $this->publishResults($this->runTests());
} }
protected function getAllowableOptions() {
return array(
'recursive' => 'boolean',
'bootstrap' => 'string'
);
}
public static function printMeta() { public static function printMeta() {
fwrite(STDOUT, Product::NAME . ' ' . Product::VERSION . ' (build date: ' . Product::DATE . ')' . "\n"); fwrite(STDOUT, Product::NAME . ' ' . Product::VERSION . ' (build date: ' . Product::DATE . ')' . "\n");
fwrite(STDOUT, ' by ' . Product::AUTHOR . "\n\n"); fwrite(STDOUT, ' by ' . Product::AUTHOR . "\n\n");

View File

@ -0,0 +1,18 @@
<?php
class TUnitException extends Exception {}
class InvalidOptionException extends TUnitException {
public function __construct($switch, $message = '') {
if (!empty($message)) {
$message = ': ' . $message;
}
$message = 'Invalid option (' . $option . ')' . $message;
parent::__construct($message);
}
}
?>

View File

@ -3,7 +3,7 @@
/** /**
* Autoload manifest * Autoload manifest
* *
* Autogenerated by manifester.php on 2009-06-19 01:41:57 * Autogenerated by manifester.php on 2009-06-19 20:34:30
* *
* @package TUnit * @package TUnit
* @version 0.4.0 * @version 0.4.0
@ -13,11 +13,13 @@
return array( return array(
'Assert' => 'TUnit/framework/Assert.php', 'Assert' => 'TUnit/framework/Assert.php',
'Autoloader' => 'TUnit/util/Autoloader.php', 'Autoloader' => 'TUnit/util/Autoloader.php',
'BaseTestRunner' => 'TUnit/framework/BaseTestRunner.php',
'Cli' => 'TUnit/util/cli.php', 'Cli' => 'TUnit/util/cli.php',
'CliSwitch' => 'TUnit/util/cli.php', 'CliSwitch' => 'TUnit/util/cli.php',
'CliSwitchCollection' => 'TUnit/util/cli.php', 'CliSwitchCollection' => 'TUnit/util/cli.php',
'CombinedTestResult' => 'TUnit/framework/result/CombinedTestResult.php', 'CombinedTestResult' => 'TUnit/framework/result/CombinedTestResult.php',
'ConsoleListener' => 'TUnit/framework/listeners/ConsoleListener.php', 'ConsoleListener' => 'TUnit/framework/listeners/ConsoleListener.php',
'ConsoleTestRunner' => 'TUnit/framework/TestRunner.php',
'Constraint' => 'TUnit/framework/constraints/Constraint.php', 'Constraint' => 'TUnit/framework/constraints/Constraint.php',
'DefaultConstraint' => 'TUnit/framework/constraints/DefaultConstraint.php', 'DefaultConstraint' => 'TUnit/framework/constraints/DefaultConstraint.php',
'EmptyConstraint' => 'TUnit/framework/constraints/SimpleConstraints.php', 'EmptyConstraint' => 'TUnit/framework/constraints/SimpleConstraints.php',
@ -30,6 +32,7 @@
'IdenticalConstraint' => 'TUnit/framework/constraints/IdenticalConstraint.php', 'IdenticalConstraint' => 'TUnit/framework/constraints/IdenticalConstraint.php',
'IgnoredTest' => 'TUnit/framework/result/FailedTest.php', 'IgnoredTest' => 'TUnit/framework/result/FailedTest.php',
'IgnoredTestResult' => 'TUnit/framework/result/IgnoredTestResult.php', 'IgnoredTestResult' => 'TUnit/framework/result/IgnoredTestResult.php',
'InvalidOptionException' => 'TUnit/framework/exceptions/Exceptions.php',
'InvocationExpectation' => 'TUnit/framework/mock/InvocationExpectation.php', 'InvocationExpectation' => 'TUnit/framework/mock/InvocationExpectation.php',
'InvocationTracker' => 'TUnit/framework/mock/InvocationTracker.php', 'InvocationTracker' => 'TUnit/framework/mock/InvocationTracker.php',
'IssetConstraint' => 'TUnit/framework/constraints/SimpleConstraints.php', 'IssetConstraint' => 'TUnit/framework/constraints/SimpleConstraints.php',
@ -47,13 +50,13 @@
'RecursiveTestIterator' => 'TUnit/util/RecursiveTestIterator.php', 'RecursiveTestIterator' => 'TUnit/util/RecursiveTestIterator.php',
'SimpleConstraint' => 'TUnit/framework/constraints/SimpleConstraints.php', 'SimpleConstraint' => 'TUnit/framework/constraints/SimpleConstraints.php',
'SingleTestResult' => 'TUnit/framework/result/SingleTestResult.php', 'SingleTestResult' => 'TUnit/framework/result/SingleTestResult.php',
'TUnitException' => 'TUnit/framework/exceptions/Exceptions.php',
'TestAccumulator' => 'TUnit/util/TestAccumulator.php', 'TestAccumulator' => 'TUnit/util/TestAccumulator.php',
'TestCase' => 'TUnit/framework/test/TestCase.php', 'TestCase' => 'TUnit/framework/test/TestCase.php',
'TestFailure' => 'TUnit/framework/result/FailedTest.php', 'TestFailure' => 'TUnit/framework/result/FailedTest.php',
'TestListener' => 'TUnit/framework/listeners/TestListener.php', 'TestListener' => 'TUnit/framework/listeners/TestListener.php',
'TestMethod' => 'TUnit/framework/test/TestMethod.php', 'TestMethod' => 'TUnit/framework/test/TestMethod.php',
'TestResult' => 'TUnit/framework/result/TestResult.php', 'TestResult' => 'TUnit/framework/result/TestResult.php',
'TestRunner' => 'TUnit/framework/TestRunner.php',
'TestSuite' => 'TUnit/framework/test/TestSuite.php', 'TestSuite' => 'TUnit/framework/test/TestSuite.php',
'Testable' => 'TUnit/framework/test/Testable.php', 'Testable' => 'TUnit/framework/test/Testable.php',
'TrueConstraint' => 'TUnit/framework/constraints/SimpleConstraints.php', 'TrueConstraint' => 'TUnit/framework/constraints/SimpleConstraints.php',

View File

@ -22,30 +22,35 @@
$switches = new CliSwitchCollection(); $switches = new CliSwitchCollection();
$switches->addSwitch(new CliSwitch(null, null, true, '<files>', 'Files and/or directories to parse for test cases')) $switches->addSwitch(new CliSwitch(null, null, true, '<files>', 'Files and/or directories to parse for test cases'))
->addSwitch(new CliSwitch('help', 'h', false, null, 'Display this help message (--usage is an alias)')) ->addSwitch(new CliSwitch('help', 'h', false, null, 'Display this help message (--usage is an alias)'))
->addSwitch(new CliSwitch('recursive', null, false, null, 'Recurse into subdirectories')); ->addSwitch(new CliSwitch('recursive', null, false, null, 'Recurse into subdirectories'))
->addSwitch(new CliSwitch('bootstrap', 'b', false, 'file', 'File to include before each test'));
array_shift($argv); array_shift($argv);
$args = Cli::parseArgs($argv, $switches); $args = Cli::parseArgs($argv, $switches);
//print_r($args); exit;
if (isset($args['help'])) { $localSwitches = $args['switches'];
$localArgs = $args['args'];
if (isset($localSwitches['help'])) {
usage(); usage();
exit(0); exit(0);
} }
if (empty($args['args'])) { if (empty($localArgs)) {
usage(); usage();
exit(1); exit(1);
} }
//accumulate tests //accumulate tests
$tests = TestAccumulator::getTests($args['args'], isset($args['recursive'])); $tests = TestAccumulator::getTests($localArgs, isset($localSwitches['recursive']));
if (empty($tests)) { if (empty($tests)) {
fwrite(STDERR, 'Found no TestCase subclasses in the given files'); fwrite(STDERR, 'Found no TestCase subclasses in the given files');
exit(1); exit(1);
} }
$runner = new TestRunner(array(new TestSuite('Main Test Suite', $tests)), array(new ConsoleListener(/*ConsoleListener::VERBOSITY_HIGH*/))); $runner = new ConsoleTestRunner(array(new TestSuite('Main Test Suite', $tests)), array(new ConsoleListener(/*ConsoleListener::VERBOSITY_HIGH*/)), $localSwitches);
$runner->run(); $runner->run();
exit(0); exit(0);