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