8000 feature #9739 [FrameworkBundle] Extract KernelTestCase from WebTestCa… · symfony/symfony@0aeb394 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0aeb394

Browse files
committed
feature #9739 [FrameworkBundle] Extract KernelTestCase from WebTestCase (johnkary)
This PR was merged into the 2.5-dev branch. Discussion ---------- [FrameworkBundle] Extract KernelTestCase from WebTestCase | Q | A | ------------- | --- | Bug fix? | No | New feature? | Yes | BC breaks? | No | Deprecations? | No | Tests pass? | Yes | Fixed tickets | None | License | MIT | Doc PR | symfony/symfony-docs#3311 Previous discussion is in #7704. Opened new PR to target master branch. This idea came to me while reading the Cookbook article [How to create a Console Command - Testing Commands](http://symfony.com/doc/master/cookbook/console/console_command.html#testing-commands) and I wanted to hear feedback from others before submitting a patch. Basically the Cookbook article states that when testing a Command that extending `WebTestCase` is a good way to get access to the Kernel and thus the Container. This struck me as weird because I was wanting to test a Command, which doesn't really have anything to do with "the web." Currently `WebTestCase` doesn't do anything internally that looks like web-specific work, and the class docblock itself states "WebTestCase is the base class for functional tests.". After a suggestion in #7704 by @beberlei, I decided to take his advice and now have the following implementation: Extracted a new class `KernelTestCase` from `WebTestCase` and instead allow WebTestCase to extend KernelTestCase. Pulled all methods up into KernelTestCase except `createClient()` because `createClient()` is focused solely on creating a Client for issuing web-based requests. Benjamin's solution provides us a clear extension point from `KernelTestCase` for Command-based tests and also provides 100% backwards-compatibility without the need to deprecate WebTestCase. Commits ------- c4f14fb Extract new base test class KernelTestClass
2 parents 4d31d2f + c4f14fb commit 0aeb394

File tree

2 files changed

+176
-147
lines changed

2 files changed

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

src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php

Lines changed: 2 additions & 147 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,14 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Test;
1313

1414
use Symfony\Bundle\FrameworkBundle\Client;
15-
use Symfony\Component\Finder\Finder;
16-
use Symfony\Component\HttpKernel\KernelInterface;
1715

1816
/**
1917
* WebTestCase is the base class for functional tests.
2018
*
2119
* @author Fabien Potencier <fabien@symfony.com>
2220
*/
23-
abstract class WebTestCase extends \PHPUnit_Framework_TestCase
21+
abstract class WebTestCase extends KernelTestCase
2422
{
25-
protected static $class;
26-
27-
/**
28-
* @var KernelInterface
29-
*/
30-
protected static $kernel;
31-
3223
/**
3324
* Creates a Client.
3425
*
@@ -39,147 +30,11 @@ abstract class WebTestCase extends \PHPUnit_Framework_TestCase
3930
*/
4031
protected static function createClient(array $options = array(), array $server = array())
4132
{
42-
if (null !== static::$kernel) {
43-
static::$kernel->shutdown();
44-
}
45-
46-
static::$kernel = static::createKernel($options);
47-
static::$kernel->boot();
33+
static::bootKernel($options);
4834

4935
$client = static::$kernel->getContainer()->get('test.client');
5036
$client->setServerParameters($server);
5137

5238
return $client;
5339
}
54-
55-
/**
56-
* Finds the directory where the phpunit.xml(.dist) is stored.
57-
*
58-
* If you run tests with the PHPUnit CLI tool, everything will work as expected.
59-
* If not, override this method in your test classes.
60-
*
61-
* @return string The directory where phpunit.xml(.dist) is stored
62-
*
63-
* @throws \RuntimeException
64-
*/
65-
protected static function getPhpUnitXmlDir()
66-
{
67-
if (!isset($_SERVER['argv']) || false === strpos($_SERVER['argv'][0], 'phpunit')) {
68-
throw new \RuntimeException('You must override the WebTestCase::createKernel() method.');
69-
}
70-
71-
$dir = static::getPhpUnitCliConfigArgument();
72-
if ($dir === null &&
73-
(is_file(getcwd().DIRECTORY_SEPARATOR.'phpunit.xml') ||
74-
is_file(getcwd().DIRECTORY_SEPARATOR.'phpunit.xml.dist'))) {
75-
$dir = getcwd();
76-
}
77-
78-
// Can't continue
79-
if ($dir === null) {
80-
throw new \RuntimeException('Unable to guess the Kernel directory.');
81-
}
82-
83-
if (!is_dir($dir)) {
84-
$dir = dirname($dir);
85-
}
86-
87-
return $dir;
88-
}
89-
90-
/**
91-
* Finds the value of the CLI configuration option.
92-
*
93-
* PHPUnit will use the last configuration argument on the command line, so this only returns
94-
* the last configuration argument.
95-
*
96-
* @return string The value of the PHPUnit CLI configuration option
97-
*/
98-
private static function getPhpUnitCliConfigArgument()
99-
{
100-
$dir = null;
101-
$reversedArgs = array_reverse($_SERVER['argv']);
102-
foreach ($reversedArgs as $argIndex => $testArg) {
103-
if (preg_match('/^-[^ \-]*c$/', $testArg) || $testArg === '--configuration') {
104-
$dir = realpath($reversedArgs[$argIndex - 1]);
105-
break;
106-
} elseif (strpos($testArg, '--configuration=') === 0) {
107-
$argPath = substr($testArg, strlen('--configuration='));
108-
$dir = realpath($argPath);
109-
break;
110-
}
111-
}
112-
113-
return $dir;
114-
}
115-
116-
/**
117-
* Attempts to guess the kernel location.
118-
*
119-
* When the Kernel is located, the file is required.
120-
*
121-
* @return string The Kernel class name
122-
*
123-
* @throws \RuntimeException
124-
*/
125-
protected static function getKernelClass()
126-
{
127-
$dir = $phpUnitDir = static::getPhpUnitXmlDir();
128-
129-
if (isset($_SERVER['KERNEL_DIR'])) {
130-
$dir = $_SERVER['KERNEL_DIR'];
131-
132-
if (!is_dir($dir) && is_dir("$phpUnitDir/$dir")) {
133-
$dir = "$phpUnitDir/$dir";
134-
}
135-
}
136-
137-
$finder = new Finder();
138-
$finder->name('*Kernel.php')->depth(0)->in($dir);
139-
$results = iterator_to_array($finder);
140-
if (!count($results)) {
141-
throw new \RuntimeException('Either set KERNEL_DIR in your phpunit.xml according to http://symfony.com/doc/current/book/testing.html#your-first-functional-test or override the WebTestCase::createKernel() method.');
142-
}
143-
144-
$file = current($results);
145-
$class = $file->getBasename('.php');
146-
147-
require_once $file;
148-
149-
return $class;
150-
}
151-
152-
/**
153-
* Creates a Kernel.
154-
*
155-
* Available options:
156-
*
157-
* * environment
158-
* * debug
159-
*
160-
* @param array $options An array of options
161-
*
162-
* @return KernelInterface A KernelInterface instance
163-
*/
164-
protected static function createKernel(array $options = array())
165-
{
166-
if (null === static::$class) {
167-
static::$class = static::getKernelClass();
168-
}
169-
170-
return new static::$class(
171-
isset($options['environment']) ? $options['environment'] : 'test',
172-
isset($options['debug']) ? $options['debug'] : true
173-
);
174-
}
175-
176-
/**
177-
* Shuts the kernel down if it was used in the test.
178-
*/
179-
protected function tearDown()
180-
{
181-
if (null !== static::$kernel) {
182-
static::$kernel->shutdown();
183-
}
184-
}
18540
}

0 commit comments

Comments
 (0)
0