[ Index ] |
|
Code source de CMS made simple 1.0.5 |
1 <?php 2 // 3 // PHP framework for testing, based on the design of "JUnit". 4 // 5 // Written by Fred Yankowski <fred@ontosys.com> 6 // OntoSys, Inc <http://www.OntoSys.com> 7 // 8 // $Id: phpunit.php,v 1.1 2005/10/24 19:27:49 rob Exp $ 9 10 // Copyright (c) 2000 Fred Yankowski 11 12 // Permission is hereby granted, free of charge, to any person 13 // obtaining a copy of this software and associated documentation 14 // files (the "Software"), to deal in the Software without 15 // restriction, including without limitation the rights to use, copy, 16 // modify, merge, publish, distribute, sublicense, and/or sell copies 17 // of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be 21 // included in all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 // SOFTWARE. 31 // 32 error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE | 33 E_CORE_ERROR | E_CORE_WARNING); 34 35 /* 36 interface Test { 37 function run(&$aTestResult); 38 function countTestCases(); 39 } 40 */ 41 42 function trace($msg) { 43 return; 44 print($msg); 45 flush(); 46 } 47 48 49 class Exception { 50 /* Emulate a Java exception, sort of... */ 51 var $message; 52 function Exception($message) { 53 $this->message = $message; 54 } 55 function getMessage() { 56 return $this->message; 57 } 58 } 59 60 class Assert { 61 function assert($boolean, $message=0) { 62 if (! $boolean) 63 $this->fail($message); 64 } 65 66 function assertEquals($expected, $actual, $message=0) { 67 if ($expected != $actual) { 68 $this->failNotEquals($expected, $actual, "expected", $message); 69 } 70 } 71 72 function assertRegexp($regexp, $actual, $message=false) { 73 if (! preg_match($regexp, $actual)) { 74 $this->failNotEquals($regexp, $actual, "pattern", $message); 75 } 76 } 77 78 function failNotEquals($expected, $actual, $expected_label, $message=0) { 79 // Private function for reporting failure to match. 80 $str = $message ? ($message . ' ') : ''; 81 $str .= "($expected_label/actual)<br>"; 82 $htmlExpected = htmlspecialchars($expected); 83 $htmlActual = htmlspecialchars($actual); 84 $str .= sprintf("<pre>%s\n--------\n%s</pre>", 85 $htmlExpected, $htmlActual); 86 $this->fail($str); 87 } 88 } 89 90 class TestCase extends Assert /* implements Test */ { 91 /* Defines context for running tests. Specific context -- such as 92 instance variables, global variables, global state -- is defined 93 by creating a subclass that specializes the setUp() and 94 tearDown() methods. A specific test is defined by a subclass 95 that specializes the runTest() method. */ 96 var $fName; 97 var $fResult; 98 var $fExceptions = array(); 99 100 function TestCase($name) { 101 $this->fName = $name; 102 } 103 104 function run($testResult=0) { 105 /* Run this single test, by calling the run() method of the 106 TestResult object which will in turn call the runBare() method 107 of this object. That complication allows the TestResult object 108 to do various kinds of progress reporting as it invokes each 109 test. Create/obtain a TestResult object if none was passed in. 110 Note that if a TestResult object was passed in, it must be by 111 reference. */ 112 if (! $testResult) 113 $testResult = $this->_createResult(); 114 $this->fResult = $testResult; 115 $testResult->run(&$this); 116 $this->fResult = 0; 117 return $testResult; 118 } 119 120 function countTestCases() { 121 return 1; 122 } 123 124 function runTest() { 125 $name = $this->name(); 126 // Since isset($this->$name) is false, no way to run defensive checks 127 $this->$name(); 128 } 129 130 function setUp() /* expect override */ { 131 //print("TestCase::setUp()<br>\n"); 132 } 133 134 function tearDown() /* possible override */ { 135 //print("TestCase::tearDown()<br>\n"); 136 } 137 138 //////////////////////////////////////////////////////////////// 139 140 141 function _createResult() /* protected */ { 142 /* override this to use specialized subclass of TestResult */ 143 return new TestResult; 144 } 145 146 function fail($message=0) { 147 //printf("TestCase::fail(%s)<br>\n", ($message) ? $message : ''); 148 /* JUnit throws AssertionFailedError here. We just record the 149 failure and carry on */ 150 $this->fExceptions[] = new Exception(&$message); 151 } 152 153 function error($message) { 154 /* report error that requires correction in the test script 155 itself, or (heaven forbid) in this testing infrastructure */ 156 printf('<b>ERROR: ' . $message . '</b><br>'); 157 $this->fResult->stop(); 158 } 159 160 function failed() { 161 return count($this->fExceptions); 162 } 163 164 function getExceptions() { 165 return $this->fExceptions; 166 } 167 168 function name() { 169 return $this->fName; 170 } 171 172 function runBare() { 173 $this->setup(); 174 $this->runTest(); 175 $this->tearDown(); 176 } 177 } 178 179 180 class TestSuite /* implements Test */ { 181 /* Compose a set of Tests (instances of TestCase or TestSuite), and 182 run them all. */ 183 var $fTests = array(); 184 185 function TestSuite($classname=false) { 186 if ($classname) { 187 // Find all methods of the given class whose name starts with 188 // "test" and add them to the test suite. We are just _barely_ 189 // able to do this with PHP's limited introspection... Note 190 // that PHP seems to store method names in lower case, and we 191 // have to avoid the constructor function for the TestCase class 192 // superclass. This will fail when $classname starts with 193 // "Test" since that will have a constructor method that will 194 // get matched below and then treated (incorrectly) as a test 195 // method. So don't name any TestCase subclasses as "Test..."! 196 if (floor(phpversion()) >= 4) { 197 // PHP4 introspection, submitted by Dylan Kuhn 198 $names = get_class_methods($classname); 199 while (list($key, $method) = each($names)) { 200 if (preg_match('/^test/', $method) && $method != "testcase") { 201 $this->addTest(new $classname($method)); 202 } 203 } 204 } 205 else { 206 $dummy = new $classname("dummy"); 207 $names = (array) $dummy; 208 while (list($key, $value) = each($names)) { 209 $type = gettype($value); 210 if ($type == "user function" && preg_match('/^test/', $key) 211 && $key != "testcase") { 212 $this->addTest(new $classname($key)); 213 } 214 } 215 } 216 } 217 } 218 219 function addTest($test) { 220 /* Add TestCase or TestSuite to this TestSuite */ 221 $this->fTests[] = $test; 222 } 223 224 function run(&$testResult) { 225 /* Run all TestCases and TestSuites comprising this TestSuite, 226 accumulating results in the given TestResult object. */ 227 reset($this->fTests); 228 while (list($na, $test) = each($this->fTests)) { 229 if ($testResult->shouldStop()) 230 break; 231 $test->run(&$testResult); 232 } 233 } 234 235 function countTestCases() { 236 /* Number of TestCases comprising this TestSuite (including those 237 in any constituent TestSuites) */ 238 $count = 0; 239 reset($fTests); 240 while (list($na, $test_case) = each($this->fTests)) { 241 $count += $test_case->countTestCases(); 242 } 243 return $count; 244 } 245 } 246 247 248 class TestFailure { 249 /* Record failure of a single TestCase, associating it with the 250 exception(s) that occurred */ 251 var $fFailedTestName; 252 var $fExceptions; 253 254 function TestFailure(&$test, &$exceptions) { 255 $this->fFailedTestName = $test->name(); 256 $this->fExceptions = $exceptions; 257 } 258 259 function getExceptions() { 260 return $this->fExceptions; 261 } 262 function getTestName() { 263 return $this->fFailedTestName; 264 } 265 } 266 267 268 class TestResult { 269 /* Collect the results of running a set of TestCases. */ 270 var $fFailures = array(); 271 var $fRunTests = 0; 272 var $fStop = false; 273 274 function TestResult() { } 275 276 function _endTest($test) /* protected */ { 277 /* specialize this for end-of-test action, such as progress 278 reports */ 279 } 280 281 function getFailures() { 282 return $this->fFailures; 283 } 284 285 function run($test) { 286 /* Run a single TestCase in the context of this TestResult */ 287 $this->_startTest($test); 288 $this->fRunTests++; 289 290 $test->runBare(); 291 292 /* this is where JUnit would catch AssertionFailedError */ 293 $exceptions = $test->getExceptions(); 294 if ($exceptions) 295 $this->fFailures[] = new TestFailure(&$test, &$exceptions); 296 $this->_endTest($test); 297 } 298 299 function countTests() { 300 return $this->fRunTests; 301 } 302 303 function shouldStop() { 304 return $this->fStop; 305 } 306 307 function _startTest($test) /* protected */ { 308 /* specialize this for start-of-test actions */ 309 } 310 311 function stop() { 312 /* set indication that the test sequence should halt */ 313 $fStop = true; 314 } 315 316 function countFailures() { 317 return count($this->fFailures); 318 } 319 } 320 321 322 class TextTestResult extends TestResult { 323 /* Specialize TestResult to produce text/html report */ 324 function TextTestResult() { 325 $this->TestResult(); // call superclass constructor 326 } 327 328 function report() { 329 /* report result of test run */ 330 $nRun = $this->countTests(); 331 $nFailures = $this->countFailures(); 332 printf("<p>%s test%s run<br>", $nRun, ($nRun == 1) ? '' : 's'); 333 printf("%s failure%s.<br>\n", $nFailures, ($nFailures == 1) ? '' : 's'); 334 if ($nFailures == 0) 335 return; 336 337 print("<ol>\n"); 338 $failures = $this->getFailures(); 339 while (list($i, $failure) = each($failures)) { 340 $failedTestName = $failure->getTestName(); 341 printf("<li>%s\n", $failedTestName); 342 343 $exceptions = $failure->getExceptions(); 344 print("<ul>"); 345 while (list($na, $exception) = each($exceptions)) 346 printf("<li>%s\n", $exception->getMessage()); 347 print("</ul>"); 348 } 349 print("</ol>\n"); 350 } 351 352 function _startTest($test) { 353 printf("%s ", $test->name()); 354 flush(); 355 } 356 357 function _endTest($test) { 358 $outcome = $test->failed() 359 ? "<font color=\"red\">FAIL</font>" 360 : "<font color=\"green\">ok</font>"; 361 printf("$outcome<br>\n"); 362 flush(); 363 } 364 } 365 366 367 class TestRunner { 368 /* Run a suite of tests and report results. */ 369 function run($suite) { 370 $result = new TextTestResult; 371 $suite->run($result); 372 $result->report(); 373 } 374 } 375 376 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Tue Apr 3 18:50:37 2007 | par Balluche grâce à PHPXref 0.7 |