1<?php 2/* 3 * This file is part of PHPUnit. 4 * 5 * (c) Sebastian Bergmann <sebastian@phpunit.de> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11/** 12 * A TestSuite is a composite of Tests. It runs a collection of test cases. 13 */ 14class PHPUnit_Framework_TestSuite implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing, IteratorAggregate 15{ 16 /** 17 * Last count of tests in this suite. 18 * 19 * @var int|null 20 */ 21 private $cachedNumTests; 22 23 /** 24 * Enable or disable the backup and restoration of the $GLOBALS array. 25 * 26 * @var bool 27 */ 28 protected $backupGlobals = null; 29 30 /** 31 * Enable or disable the backup and restoration of static attributes. 32 * 33 * @var bool 34 */ 35 protected $backupStaticAttributes = null; 36 37 /** 38 * @var bool 39 */ 40 private $beStrictAboutChangesToGlobalState = null; 41 42 /** 43 * @var bool 44 */ 45 protected $runTestInSeparateProcess = false; 46 47 /** 48 * The name of the test suite. 49 * 50 * @var string 51 */ 52 protected $name = ''; 53 54 /** 55 * The test groups of the test suite. 56 * 57 * @var array 58 */ 59 protected $groups = []; 60 61 /** 62 * The tests in the test suite. 63 * 64 * @var array 65 */ 66 protected $tests = []; 67 68 /** 69 * The number of tests in the test suite. 70 * 71 * @var int 72 */ 73 protected $numTests = -1; 74 75 /** 76 * @var bool 77 */ 78 protected $testCase = false; 79 80 /** 81 * @var array 82 */ 83 protected $foundClasses = []; 84 85 /** 86 * @var PHPUnit_Runner_Filter_Factory 87 */ 88 private $iteratorFilter = null; 89 90 /** 91 * @var string[] 92 */ 93 private $declaredClasses; 94 95 /** 96 * Constructs a new TestSuite: 97 * 98 * - PHPUnit_Framework_TestSuite() constructs an empty TestSuite. 99 * 100 * - PHPUnit_Framework_TestSuite(ReflectionClass) constructs a 101 * TestSuite from the given class. 102 * 103 * - PHPUnit_Framework_TestSuite(ReflectionClass, String) 104 * constructs a TestSuite from the given class with the given 105 * name. 106 * 107 * - PHPUnit_Framework_TestSuite(String) either constructs a 108 * TestSuite from the given class (if the passed string is the 109 * name of an existing class) or constructs an empty TestSuite 110 * with the given name. 111 * 112 * @param mixed $theClass 113 * @param string $name 114 * 115 * @throws PHPUnit_Framework_Exception 116 */ 117 public function __construct($theClass = '', $name = '') 118 { 119 $this->declaredClasses = get_declared_classes(); 120 121 $argumentsValid = false; 122 123 if (is_object($theClass) && 124 $theClass instanceof ReflectionClass) { 125 $argumentsValid = true; 126 } elseif (is_string($theClass) && 127 $theClass !== '' && 128 class_exists($theClass, false)) { 129 $argumentsValid = true; 130 131 if ($name == '') { 132 $name = $theClass; 133 } 134 135 $theClass = new ReflectionClass($theClass); 136 } elseif (is_string($theClass)) { 137 $this->setName($theClass); 138 139 return; 140 } 141 142 if (!$argumentsValid) { 143 throw new PHPUnit_Framework_Exception; 144 } 145 146 if (!$theClass->isSubclassOf('PHPUnit_Framework_TestCase')) { 147 throw new PHPUnit_Framework_Exception( 148 'Class "' . $theClass->name . '" does not extend PHPUnit_Framework_TestCase.' 149 ); 150 } 151 152 if ($name != '') { 153 $this->setName($name); 154 } else { 155 $this->setName($theClass->getName()); 156 } 157 158 $constructor = $theClass->getConstructor(); 159 160 if ($constructor !== null && 161 !$constructor->isPublic()) { 162 $this->addTest( 163 self::warning( 164 sprintf( 165 'Class "%s" has no public constructor.', 166 $theClass->getName() 167 ) 168 ) 169 ); 170 171 return; 172 } 173 174 foreach ($theClass->getMethods() as $method) { 175 $this->addTestMethod($theClass, $method); 176 } 177 178 if (empty($this->tests)) { 179 $this->addTest( 180 self::warning( 181 sprintf( 182 'No tests found in class "%s".', 183 $theClass->getName() 184 ) 185 ) 186 ); 187 } 188 189 $this->testCase = true; 190 } 191 192 /** 193 * Returns a string representation of the test suite. 194 * 195 * @return string 196 */ 197 public function toString() 198 { 199 return $this->getName(); 200 } 201 202 /** 203 * Adds a test to the suite. 204 * 205 * @param PHPUnit_Framework_Test $test 206 * @param array $groups 207 */ 208 public function addTest(PHPUnit_Framework_Test $test, $groups = []) 209 { 210 $class = new ReflectionClass($test); 211 212 if (!$class->isAbstract()) { 213 $this->tests[] = $test; 214 $this->numTests = -1; 215 216 if ($test instanceof self && 217 empty($groups)) { 218 $groups = $test->getGroups(); 219 } 220 221 if (empty($groups)) { 222 $groups = ['default']; 223 } 224 225 foreach ($groups as $group) { 226 if (!isset($this->groups[$group])) { 227 $this->groups[$group] = [$test]; 228 } else { 229 $this->groups[$group][] = $test; 230 } 231 } 232 233 if ($test instanceof PHPUnit_Framework_TestCase) { 234 $test->setGroups($groups); 235 } 236 } 237 } 238 239 /** 240 * Adds the tests from the given class to the suite. 241 * 242 * @param mixed $testClass 243 * 244 * @throws PHPUnit_Framework_Exception 245 */ 246 public function addTestSuite($testClass) 247 { 248 if (is_string($testClass) && class_exists($testClass)) { 249 $testClass = new ReflectionClass($testClass); 250 } 251 252 if (!is_object($testClass)) { 253 throw PHPUnit_Util_InvalidArgumentHelper::factory( 254 1, 255 'class name or object' 256 ); 257 } 258 259 if ($testClass instanceof self) { 260 $this->addTest($testClass); 261 } elseif ($testClass instanceof ReflectionClass) { 262 $suiteMethod = false; 263 264 if (!$testClass->isAbstract()) { 265 if ($testClass->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { 266 $method = $testClass->getMethod( 267 PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME 268 ); 269 270 if ($method->isStatic()) { 271 $this->addTest( 272 $method->invoke(null, $testClass->getName()) 273 ); 274 275 $suiteMethod = true; 276 } 277 } 278 } 279 280 if (!$suiteMethod && !$testClass->isAbstract() && $testClass->isSubclassOf(PHPUnit_Framework_TestCase::class)) { 281 $this->addTest(new self($testClass)); 282 } 283 } else { 284 throw new PHPUnit_Framework_Exception; 285 } 286 } 287 288 /** 289 * Wraps both <code>addTest()</code> and <code>addTestSuite</code> 290 * as well as the separate import statements for the user's convenience. 291 * 292 * If the named file cannot be read or there are no new tests that can be 293 * added, a <code>PHPUnit_Framework_WarningTestCase</code> will be created instead, 294 * leaving the current test run untouched. 295 * 296 * @param string $filename 297 * 298 * @throws PHPUnit_Framework_Exception 299 */ 300 public function addTestFile($filename) 301 { 302 if (!is_string($filename)) { 303 throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); 304 } 305 306 if (file_exists($filename) && substr($filename, -5) == '.phpt') { 307 $this->addTest( 308 new PHPUnit_Extensions_PhptTestCase($filename) 309 ); 310 311 return; 312 } 313 314 // The given file may contain further stub classes in addition to the 315 // test class itself. Figure out the actual test class. 316 $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename); 317 $newClasses = array_diff(get_declared_classes(), $this->declaredClasses); 318 319 // The diff is empty in case a parent class (with test methods) is added 320 // AFTER a child class that inherited from it. To account for that case, 321 // cumulate all discovered classes, so the parent class may be found in 322 // a later invocation. 323 if (!empty($newClasses)) { 324 // On the assumption that test classes are defined first in files, 325 // process discovered classes in approximate LIFO order, so as to 326 // avoid unnecessary reflection. 327 $this->foundClasses = array_merge($newClasses, $this->foundClasses); 328 $this->declaredClasses = get_declared_classes(); 329 } 330 331 // The test class's name must match the filename, either in full, or as 332 // a PEAR/PSR-0 prefixed shortname ('NameSpace_ShortName'), or as a 333 // PSR-1 local shortname ('NameSpace\ShortName'). The comparison must be 334 // anchored to prevent false-positive matches (e.g., 'OtherShortName'). 335 $shortname = basename($filename, '.php'); 336 $shortnameRegEx = '/(?:^|_|\\\\)' . preg_quote($shortname, '/') . '$/'; 337 338 foreach ($this->foundClasses as $i => $className) { 339 if (preg_match($shortnameRegEx, $className)) { 340 $class = new ReflectionClass($className); 341 342 if ($class->getFileName() == $filename) { 343 $newClasses = [$className]; 344 unset($this->foundClasses[$i]); 345 break; 346 } 347 } 348 } 349 350 foreach ($newClasses as $className) { 351 if (strpos($className, 'PHPUnit_Framework') === 0) { 352 continue; 353 } 354 355 $class = new ReflectionClass($className); 356 357 if (!$class->isAbstract()) { 358 if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { 359 $method = $class->getMethod( 360 PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME 361 ); 362 363 if ($method->isStatic()) { 364 $this->addTest($method->invoke(null, $className)); 365 } 366 } elseif ($class->implementsInterface('PHPUnit_Framework_Test')) { 367 $this->addTestSuite($class); 368 } 369 } 370 } 371 372 $this->numTests = -1; 373 } 374 375 /** 376 * Wrapper for addTestFile() that adds multiple test files. 377 * 378 * @param array|Iterator $filenames 379 * 380 * @throws PHPUnit_Framework_Exception 381 */ 382 public function addTestFiles($filenames) 383 { 384 if (!(is_array($filenames) || 385 (is_object($filenames) && $filenames instanceof Iterator))) { 386 throw PHPUnit_Util_InvalidArgumentHelper::factory( 387 1, 388 'array or iterator' 389 ); 390 } 391 392 foreach ($filenames as $filename) { 393 $this->addTestFile((string) $filename); 394 } 395 } 396 397 /** 398 * Counts the number of test cases that will be run by this test. 399 * 400 * @param bool $preferCache Indicates if cache is preferred. 401 * 402 * @return int 403 */ 404 public function count($preferCache = false) 405 { 406 if ($preferCache && $this->cachedNumTests !== null) { 407 $numTests = $this->cachedNumTests; 408 } else { 409 $numTests = 0; 410 411 foreach ($this as $test) { 412 $numTests += count($test); 413 } 414 415 $this->cachedNumTests = $numTests; 416 } 417 418 return $numTests; 419 } 420 421 /** 422 * @param ReflectionClass $theClass 423 * @param string $name 424 * 425 * @return PHPUnit_Framework_Test 426 * 427 * @throws PHPUnit_Framework_Exception 428 */ 429 public static function createTest(ReflectionClass $theClass, $name) 430 { 431 $className = $theClass->getName(); 432 433 if (!$theClass->isInstantiable()) { 434 return self::warning( 435 sprintf('Cannot instantiate class "%s".', $className) 436 ); 437 } 438 439 $backupSettings = PHPUnit_Util_Test::getBackupSettings( 440 $className, 441 $name 442 ); 443 444 $preserveGlobalState = PHPUnit_Util_Test::getPreserveGlobalStateSettings( 445 $className, 446 $name 447 ); 448 449 $runTestInSeparateProcess = PHPUnit_Util_Test::getProcessIsolationSettings( 450 $className, 451 $name 452 ); 453 454 $constructor = $theClass->getConstructor(); 455 456 if ($constructor !== null) { 457 $parameters = $constructor->getParameters(); 458 459 // TestCase() or TestCase($name) 460 if (count($parameters) < 2) { 461 $test = new $className; 462 } // TestCase($name, $data) 463 else { 464 try { 465 $data = PHPUnit_Util_Test::getProvidedData( 466 $className, 467 $name 468 ); 469 } catch (PHPUnit_Framework_IncompleteTestError $e) { 470 $message = sprintf( 471 'Test for %s::%s marked incomplete by data provider', 472 $className, 473 $name 474 ); 475 476 $_message = $e->getMessage(); 477 478 if (!empty($_message)) { 479 $message .= "\n" . $_message; 480 } 481 482 $data = self::incompleteTest($className, $name, $message); 483 } catch (PHPUnit_Framework_SkippedTestError $e) { 484 $message = sprintf( 485 'Test for %s::%s skipped by data provider', 486 $className, 487 $name 488 ); 489 490 $_message = $e->getMessage(); 491 492 if (!empty($_message)) { 493 $message .= "\n" . $_message; 494 } 495 496 $data = self::skipTest($className, $name, $message); 497 } catch (Throwable $_t) { 498 $t = $_t; 499 } catch (Exception $_t) { 500 $t = $_t; 501 } 502 503 if (isset($t)) { 504 $message = sprintf( 505 'The data provider specified for %s::%s is invalid.', 506 $className, 507 $name 508 ); 509 510 $_message = $t->getMessage(); 511 512 if (!empty($_message)) { 513 $message .= "\n" . $_message; 514 } 515 516 $data = self::warning($message); 517 } 518 519 // Test method with @dataProvider. 520 if (isset($data)) { 521 $test = new PHPUnit_Framework_TestSuite_DataProvider( 522 $className . '::' . $name 523 ); 524 525 if (empty($data)) { 526 $data = self::warning( 527 sprintf( 528 'No tests found in suite "%s".', 529 $test->getName() 530 ) 531 ); 532 } 533 534 $groups = PHPUnit_Util_Test::getGroups($className, $name); 535 536 if ($data instanceof PHPUnit_Framework_WarningTestCase || 537 $data instanceof PHPUnit_Framework_SkippedTestCase || 538 $data instanceof PHPUnit_Framework_IncompleteTestCase) { 539 $test->addTest($data, $groups); 540 } else { 541 foreach ($data as $_dataName => $_data) { 542 $_test = new $className($name, $_data, $_dataName); 543 544 if ($runTestInSeparateProcess) { 545 $_test->setRunTestInSeparateProcess(true); 546 547 if ($preserveGlobalState !== null) { 548 $_test->setPreserveGlobalState($preserveGlobalState); 549 } 550 } 551 552 if ($backupSettings['backupGlobals'] !== null) { 553 $_test->setBackupGlobals( 554 $backupSettings['backupGlobals'] 555 ); 556 } 557 558 if ($backupSettings['backupStaticAttributes'] !== null) { 559 $_test->setBackupStaticAttributes( 560 $backupSettings['backupStaticAttributes'] 561 ); 562 } 563 564 $test->addTest($_test, $groups); 565 } 566 } 567 } else { 568 $test = new $className; 569 } 570 } 571 } 572 573 if (!isset($test)) { 574 throw new PHPUnit_Framework_Exception('No valid test provided.'); 575 } 576 577 if ($test instanceof PHPUnit_Framework_TestCase) { 578 $test->setName($name); 579 580 if ($runTestInSeparateProcess) { 581 $test->setRunTestInSeparateProcess(true); 582 583 if ($preserveGlobalState !== null) { 584 $test->setPreserveGlobalState($preserveGlobalState); 585 } 586 } 587 588 if ($backupSettings['backupGlobals'] !== null) { 589 $test->setBackupGlobals($backupSettings['backupGlobals']); 590 } 591 592 if ($backupSettings['backupStaticAttributes'] !== null) { 593 $test->setBackupStaticAttributes( 594 $backupSettings['backupStaticAttributes'] 595 ); 596 } 597 } 598 599 return $test; 600 } 601 602 /** 603 * Creates a default TestResult object. 604 * 605 * @return PHPUnit_Framework_TestResult 606 */ 607 protected function createResult() 608 { 609 return new PHPUnit_Framework_TestResult; 610 } 611 612 /** 613 * Returns the name of the suite. 614 * 615 * @return string 616 */ 617 public function getName() 618 { 619 return $this->name; 620 } 621 622 /** 623 * Returns the test groups of the suite. 624 * 625 * @return array 626 */ 627 public function getGroups() 628 { 629 return array_keys($this->groups); 630 } 631 632 public function getGroupDetails() 633 { 634 return $this->groups; 635 } 636 637 /** 638 * Set tests groups of the test case 639 * 640 * @param array $groups 641 */ 642 public function setGroupDetails(array $groups) 643 { 644 $this->groups = $groups; 645 } 646 647 /** 648 * Runs the tests and collects their result in a TestResult. 649 * 650 * @param PHPUnit_Framework_TestResult $result 651 * 652 * @return PHPUnit_Framework_TestResult 653 */ 654 public function run(PHPUnit_Framework_TestResult $result = null) 655 { 656 if ($result === null) { 657 $result = $this->createResult(); 658 } 659 660 if (count($this) == 0) { 661 return $result; 662 } 663 664 $hookMethods = PHPUnit_Util_Test::getHookMethods($this->name); 665 666 $result->startTestSuite($this); 667 668 try { 669 $this->setUp(); 670 671 foreach ($hookMethods['beforeClass'] as $beforeClassMethod) { 672 if ($this->testCase === true && 673 class_exists($this->name, false) && 674 method_exists($this->name, $beforeClassMethod)) { 675 if ($missingRequirements = PHPUnit_Util_Test::getMissingRequirements($this->name, $beforeClassMethod)) { 676 $this->markTestSuiteSkipped(implode(PHP_EOL, $missingRequirements)); 677 } 678 679 call_user_func([$this->name, $beforeClassMethod]); 680 } 681 } 682 } catch (PHPUnit_Framework_SkippedTestSuiteError $e) { 683 $numTests = count($this); 684 685 for ($i = 0; $i < $numTests; $i++) { 686 $result->startTest($this); 687 $result->addFailure($this, $e, 0); 688 $result->endTest($this, 0); 689 } 690 691 $this->tearDown(); 692 $result->endTestSuite($this); 693 694 return $result; 695 } catch (Throwable $_t) { 696 $t = $_t; 697 } catch (Exception $_t) { 698 $t = $_t; 699 } 700 701 if (isset($t)) { 702 $numTests = count($this); 703 704 for ($i = 0; $i < $numTests; $i++) { 705 if ($result->shouldStop()) { 706 break; 707 } 708 709 $result->startTest($this); 710 $result->addError($this, $t, 0); 711 $result->endTest($this, 0); 712 } 713 714 $this->tearDown(); 715 $result->endTestSuite($this); 716 717 return $result; 718 } 719 720 foreach ($this as $test) { 721 if ($result->shouldStop()) { 722 break; 723 } 724 725 if ($test instanceof PHPUnit_Framework_TestCase || 726 $test instanceof self) { 727 $test->setBeStrictAboutChangesToGlobalState($this->beStrictAboutChangesToGlobalState); 728 $test->setBackupGlobals($this->backupGlobals); 729 $test->setBackupStaticAttributes($this->backupStaticAttributes); 730 $test->setRunTestInSeparateProcess($this->runTestInSeparateProcess); 731 } 732 733 $test->run($result); 734 } 735 736 foreach ($hookMethods['afterClass'] as $afterClassMethod) { 737 if ($this->testCase === true && class_exists($this->name, false) && method_exists($this->name, $afterClassMethod)) { 738 call_user_func([$this->name, $afterClassMethod]); 739 } 740 } 741 742 $this->tearDown(); 743 744 $result->endTestSuite($this); 745 746 return $result; 747 } 748 749 /** 750 * @param bool $runTestInSeparateProcess 751 * 752 * @throws PHPUnit_Framework_Exception 753 */ 754 public function setRunTestInSeparateProcess($runTestInSeparateProcess) 755 { 756 if (is_bool($runTestInSeparateProcess)) { 757 $this->runTestInSeparateProcess = $runTestInSeparateProcess; 758 } else { 759 throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); 760 } 761 } 762 763 /** 764 * Runs a test. 765 * 766 * @deprecated 767 * 768 * @param PHPUnit_Framework_Test $test 769 * @param PHPUnit_Framework_TestResult $result 770 */ 771 public function runTest(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result) 772 { 773 $test->run($result); 774 } 775 776 /** 777 * Sets the name of the suite. 778 * 779 * @param string 780 */ 781 public function setName($name) 782 { 783 $this->name = $name; 784 } 785 786 /** 787 * Returns the test at the given index. 788 * 789 * @param int|false 790 * 791 * @return PHPUnit_Framework_Test 792 */ 793 public function testAt($index) 794 { 795 if (isset($this->tests[$index])) { 796 return $this->tests[$index]; 797 } else { 798 return false; 799 } 800 } 801 802 /** 803 * Returns the tests as an enumeration. 804 * 805 * @return array 806 */ 807 public function tests() 808 { 809 return $this->tests; 810 } 811 812 /** 813 * Set tests of the test suite 814 * 815 * @param array $tests 816 */ 817 public function setTests(array $tests) 818 { 819 $this->tests = $tests; 820 } 821 822 /** 823 * Mark the test suite as skipped. 824 * 825 * @param string $message 826 * 827 * @throws PHPUnit_Framework_SkippedTestSuiteError 828 */ 829 public function markTestSuiteSkipped($message = '') 830 { 831 throw new PHPUnit_Framework_SkippedTestSuiteError($message); 832 } 833 834 /** 835 * @param ReflectionClass $class 836 * @param ReflectionMethod $method 837 */ 838 protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method) 839 { 840 if (!$this->isTestMethod($method)) { 841 return; 842 } 843 844 $name = $method->getName(); 845 846 if (!$method->isPublic()) { 847 $this->addTest( 848 self::warning( 849 sprintf( 850 'Test method "%s" in test class "%s" is not public.', 851 $name, 852 $class->getName() 853 ) 854 ) 855 ); 856 857 return; 858 } 859 860 $test = self::createTest($class, $name); 861 862 if ($test instanceof PHPUnit_Framework_TestCase || 863 $test instanceof PHPUnit_Framework_TestSuite_DataProvider) { 864 $test->setDependencies( 865 PHPUnit_Util_Test::getDependencies($class->getName(), $name) 866 ); 867 } 868 869 $this->addTest( 870 $test, 871 PHPUnit_Util_Test::getGroups($class->getName(), $name) 872 ); 873 } 874 875 /** 876 * @param ReflectionMethod $method 877 * 878 * @return bool 879 */ 880 public static function isTestMethod(ReflectionMethod $method) 881 { 882 if (strpos($method->name, 'test') === 0) { 883 return true; 884 } 885 886 // @scenario on TestCase::testMethod() 887 // @test on TestCase::testMethod() 888 $docComment = $method->getDocComment(); 889 890 return strpos($docComment, '@test') !== false || 891 strpos($docComment, '@scenario') !== false; 892 } 893 894 /** 895 * @param string $message 896 * 897 * @return PHPUnit_Framework_WarningTestCase 898 */ 899 protected static function warning($message) 900 { 901 return new PHPUnit_Framework_WarningTestCase($message); 902 } 903 904 /** 905 * @param string $class 906 * @param string $methodName 907 * @param string $message 908 * 909 * @return PHPUnit_Framework_SkippedTestCase 910 */ 911 protected static function skipTest($class, $methodName, $message) 912 { 913 return new PHPUnit_Framework_SkippedTestCase($class, $methodName, $message); 914 } 915 916 /** 917 * @param string $class 918 * @param string $methodName 919 * @param string $message 920 * 921 * @return PHPUnit_Framework_IncompleteTestCase 922 */ 923 protected static function incompleteTest($class, $methodName, $message) 924 { 925 return new PHPUnit_Framework_IncompleteTestCase($class, $methodName, $message); 926 } 927 928 /** 929 * @param bool $beStrictAboutChangesToGlobalState 930 */ 931 public function setBeStrictAboutChangesToGlobalState($beStrictAboutChangesToGlobalState) 932 { 933 if (is_null($this->beStrictAboutChangesToGlobalState) && is_bool($beStrictAboutChangesToGlobalState)) { 934 $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; 935 } 936 } 937 938 /** 939 * @param bool $backupGlobals 940 */ 941 public function setBackupGlobals($backupGlobals) 942 { 943 if (is_null($this->backupGlobals) && is_bool($backupGlobals)) { 944 $this->backupGlobals = $backupGlobals; 945 } 946 } 947 948 /** 949 * @param bool $backupStaticAttributes 950 */ 951 public function setBackupStaticAttributes($backupStaticAttributes) 952 { 953 if (is_null($this->backupStaticAttributes) && 954 is_bool($backupStaticAttributes)) { 955 $this->backupStaticAttributes = $backupStaticAttributes; 956 } 957 } 958 959 /** 960 * Returns an iterator for this test suite. 961 * 962 * @return RecursiveIteratorIterator 963 */ 964 public function getIterator() 965 { 966 $iterator = new PHPUnit_Util_TestSuiteIterator($this); 967 968 if ($this->iteratorFilter !== null) { 969 $iterator = $this->iteratorFilter->factory($iterator, $this); 970 } 971 972 return $iterator; 973 } 974 975 public function injectFilter(PHPUnit_Runner_Filter_Factory $filter) 976 { 977 $this->iteratorFilter = $filter; 978 foreach ($this as $test) { 979 if ($test instanceof self) { 980 $test->injectFilter($filter); 981 } 982 } 983 } 984 985 /** 986 * Template Method that is called before the tests 987 * of this test suite are run. 988 */ 989 protected function setUp() 990 { 991 } 992 993 /** 994 * Template Method that is called after the tests 995 * of this test suite have finished running. 996 */ 997 protected function tearDown() 998 { 999 } 1000} 1001