KernelTestCase.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\FrameworkBundle\Test;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\DependencyInjection\ResettableContainerInterface;
  13. use Symfony\Component\Finder\Finder;
  14. use Symfony\Component\HttpKernel\KernelInterface;
  15. /**
  16. * KernelTestCase is the base class for tests needing a Kernel.
  17. *
  18. * @author Fabien Potencier <fabien@symfony.com>
  19. */
  20. abstract class KernelTestCase extends TestCase
  21. {
  22. protected static $class;
  23. /**
  24. * @var KernelInterface
  25. */
  26. protected static $kernel;
  27. /**
  28. * Finds the directory where the phpunit.xml(.dist) is stored.
  29. *
  30. * If you run tests with the PHPUnit CLI tool, everything will work as expected.
  31. * If not, override this method in your test classes.
  32. *
  33. * @return string The directory where phpunit.xml(.dist) is stored
  34. *
  35. * @throws \RuntimeException
  36. */
  37. protected static function getPhpUnitXmlDir()
  38. {
  39. if (!isset($_SERVER['argv']) || false === strpos($_SERVER['argv'][0], 'phpunit')) {
  40. throw new \RuntimeException('You must override the KernelTestCase::createKernel() method.');
  41. }
  42. $dir = static::getPhpUnitCliConfigArgument();
  43. if (null === $dir &&
  44. (is_file(getcwd().\DIRECTORY_SEPARATOR.'phpunit.xml') ||
  45. is_file(getcwd().\DIRECTORY_SEPARATOR.'phpunit.xml.dist'))) {
  46. $dir = getcwd();
  47. }
  48. // Can't continue
  49. if (null === $dir) {
  50. throw new \RuntimeException('Unable to guess the Kernel directory.');
  51. }
  52. if (!is_dir($dir)) {
  53. $dir = \dirname($dir);
  54. }
  55. return $dir;
  56. }
  57. /**
  58. * Finds the value of the CLI configuration option.
  59. *
  60. * PHPUnit will use the last configuration argument on the command line, so this only returns
  61. * the last configuration argument.
  62. *
  63. * @return string The value of the PHPUnit CLI configuration option
  64. */
  65. private static function getPhpUnitCliConfigArgument()
  66. {
  67. $dir = null;
  68. $reversedArgs = array_reverse($_SERVER['argv']);
  69. foreach ($reversedArgs as $argIndex => $testArg) {
  70. if (preg_match('/^-[^ \-]*c$/', $testArg) || '--configuration' === $testArg) {
  71. $dir = realpath($reversedArgs[$argIndex - 1]);
  72. break;
  73. } elseif (0 === strpos($testArg, '--configuration=')) {
  74. $argPath = substr($testArg, \strlen('--configuration='));
  75. $dir = realpath($argPath);
  76. break;
  77. } elseif (0 === strpos($testArg, '-c')) {
  78. $argPath = substr($testArg, \strlen('-c'));
  79. $dir = realpath($argPath);
  80. break;
  81. }
  82. }
  83. return $dir;
  84. }
  85. /**
  86. * Attempts to guess the kernel location.
  87. *
  88. * When the Kernel is located, the file is required.
  89. *
  90. * @return string The Kernel class name
  91. *
  92. * @throws \RuntimeException
  93. */
  94. protected static function getKernelClass()
  95. {
  96. if (isset($_SERVER['KERNEL_DIR']) || isset($_ENV['KERNEL_DIR'])) {
  97. $dir = isset($_SERVER['KERNEL_DIR']) ? $_SERVER['KERNEL_DIR'] : $_ENV['KERNEL_DIR'];
  98. if (!is_dir($dir)) {
  99. $phpUnitDir = static::getPhpUnitXmlDir();
  100. if (is_dir("$phpUnitDir/$dir")) {
  101. $dir = "$phpUnitDir/$dir";
  102. }
  103. }
  104. } else {
  105. $dir = static::getPhpUnitXmlDir();
  106. }
  107. $finder = new Finder();
  108. $finder->name('*Kernel.php')->depth(0)->in($dir);
  109. $results = iterator_to_array($finder);
  110. if (!\count($results)) {
  111. throw new \RuntimeException('Either set KERNEL_DIR in your phpunit.xml according to https://symfony.com/doc/current/book/testing.html#your-first-functional-test or override the WebTestCase::createKernel() method.');
  112. }
  113. $file = current($results);
  114. $class = $file->getBasename('.php');
  115. require_once $file;
  116. return $class;
  117. }
  118. /**
  119. * Boots the Kernel for this test.
  120. */
  121. protected static function bootKernel(array $options = array())
  122. {
  123. static::ensureKernelShutdown();
  124. static::$kernel = static::createKernel($options);
  125. static::$kernel->boot();
  126. }
  127. /**
  128. * Creates a Kernel.
  129. *
  130. * Available options:
  131. *
  132. * * environment
  133. * * debug
  134. *
  135. * @return KernelInterface A KernelInterface instance
  136. */
  137. protected static function createKernel(array $options = array())
  138. {
  139. if (null === static::$class) {
  140. static::$class = static::getKernelClass();
  141. }
  142. return new static::$class(
  143. isset($options['environment']) ? $options['environment'] : 'test',
  144. isset($options['debug']) ? $options['debug'] : true
  145. );
  146. }
  147. /**
  148. * Shuts the kernel down if it was used in the test.
  149. */
  150. protected static function ensureKernelShutdown()
  151. {
  152. if (null !== static::$kernel) {
  153. $container = static::$kernel->getContainer();
  154. static::$kernel->shutdown();
  155. if ($container instanceof ResettableContainerInterface) {
  156. $container->reset();
  157. }
  158. }
  159. }
  160. /**
  161. * Clean up Kernel usage in this test.
  162. */
  163. protected function tearDown()
  164. {
  165. static::ensureKernelShutdown();
  166. }
  167. }