@@ -4,22 +4,30 @@ Testing Your Application
44========================
55
66This chapter describes how to test your application against your reverse proxy.
7-
8- The FOSHttpCache library provides base test case classes to help you write
9- functional tests. This is helpful to test the way your application sets caching
10- headers and invalidates cached content.
11-
12- By having your test classes extend one of the test case classes, you get:
13-
14- * independent tests: all previously cached content is removed in the tests
15- ``setUp `` method. The way this is done depends on which reverse proxy you use;
16- * an instance of this library’s client that is configured to talk to your
17- reverse proxy server. See reverse proxy specific sections for details;
18- * convenience methods for executing HTTP requests to your application:
19- ``$this->getHttpAdapter() `` and ``$this->getResponse() ``;
20- * custom assertions ``assertHit `` and ``assertMiss `` for validating a cache
7+ By running your tests against a live instance of your caching proxy, you can
8+ validate the caching headers that your application sets, and the invalidation
9+ rules that it defines.
10+
11+ The FOSHttpCache library provides traits and base test classes to help you write
12+ functional tests. Using the traits, you can extend your own (or your
13+ framework’s) base test classes. For convenience, you can also extend the
14+ FOSHttpCache base test classes, as they include a sensible set of traits by
15+ default.
16+
17+ By using the traits, you get:
18+
19+ * independent tests: all previously cached content is removed in the test’s
20+ ``setUp() `` method;
21+ * an instance of this library’s proxy client that is configured to talk to your
22+ proxy server for invalidation requests;
23+ * a convenience method for executing HTTP requests to your caching proxy:
24+ ``$this->getResponse() ``;
25+ * custom assertions ``assertHit() `` and ``assertMiss() `` for validating a cache
2126 hit/miss.
2227
28+ Configuration
29+ -------------
30+
2331The recommended way to configure the test case is by setting constants
2432in your ``phpunit.xml ``. Alternatively, you can override the getter methods.
2533
@@ -85,18 +93,31 @@ You can override getters in your test class in the following way::
8593 }
8694 }
8795
88- VarnishTestCase
89- ---------------
96+ Traits
97+ ------
9098
91- Configuration
92- '''''''''''''
99+ Caching Proxy Server Traits
100+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
93101
94- By default, the ``VarnishTestCase `` starts and stops a Varnish server for you.
95- Make sure ``symfony/process `` is available in your project:
102+ FOSHttpCache provides three caching proxy traits that:
96103
97- .. code-block :: bash
104+ * if necessary, start your caching proxy server before running the tests;
105+ * clear any cached content between tests to guarantee test isolation;
106+ * if necessary, stop the caching proxy server after the tests have finished;
107+ * provide ``getProxyClient() ``, which returns the right
108+ :doc: `proxy client <proxy-clients >` for your proxy server.
98109
99- $ composer require symfony/process
110+ You only need to include one of these traits in your test classes. Which one
111+ you need (``VarnishTest ``, ``NginxTest `` or ``SymfonyTest ``) depends on the
112+ caching proxy server that you use.
113+
114+ VarnishTest Trait
115+ """""""""""""""""
116+
117+ .. include :: includes/symfony-process.rst
118+
119+ Then configure the following parameters. The web server hostname and path to
120+ your VCL file are required.
100121
101122Then set your Varnish configuration (VCL) file. Configuration is handled either
102123by overwriting the getter or by defining a PHP constant. You can set the
@@ -106,6 +127,7 @@ configuration parameters are:
106127======================= ========================= ================================================== ===========================================
107128Constant Getter Default Description
108129======================= ========================= ================================================== ===========================================
130+ ``WEB_SERVER_HOSTNAME `` ``getHostName() `` hostname your application can be reached at
109131``VARNISH_FILE `` ``getConfigFile() `` your Varnish configuration (VCL) file
110132``VARNISH_BINARY `` ``getBinary() `` ``varnishd `` your Varnish binary
111133``VARNISH_PORT `` ``getCachingProxyPort() `` ``6181 `` port Varnish listens on
@@ -134,54 +156,31 @@ For the `assertHit` and `assertMiss` assertions to work, you need to add a
134156:ref: `custom X-Cache header <varnish_debugging >` to responses served
135157by your Varnish.
136158
137- NginxTestCase
138- -------------
139-
140- Configuration
141- '''''''''''''
159+ NginxTest Trait
160+ """""""""""""""
142161
143- By default, the ``NginxTestCase `` starts and stops the NGINX server for you and
144- deletes all cached contents. Make sure ``symfony/process `` is available in your
145- project:
162+ .. include :: includes/symfony-process.rst
146163
147- .. code-block :: bash
148-
149- $ composer require symfony/process
150-
151- You have to set your NGINX configuration file. All available configuration
152- parameters are shown below.
164+ Then configure the following parameters. The web server hostname and path to
165+ your NGINX configuration file are required.
153166
154167======================= ========================= ================================================ ===========================================
155168Constant Getter Default Description
156169======================= ========================= ================================================ ===========================================
170+ ``WEB_SERVER_HOSTNAME `` ``getHostName() `` hostname your application can be reached at
157171``NGINX_FILE `` ``getConfigFile() `` your NGINX configuration file
158172``NGINX_BINARY `` ``getBinary() `` ``nginx `` your NGINX binary
159173``NGINX_PORT `` ``getCachingProxyPort() `` ``8088 `` port NGINX listens on
160174``NGINX_CACHE_PATH `` ``getCacheDir() `` ``sys_get_temp_dir() `` + ``/foshttpcache-nginx `` directory to use for cache
161175 Must match `proxy_cache_path ` directive in
162176 your configuration file.
163- ``WEB_SERVER_HOSTNAME `` ``getHostName() `` hostname your application can be reached at
164177======================= ========================= ================================================ ===========================================
165178
166- Enable Assertions
167- '''''''''''''''''
179+ SymfonyTest Trait
180+ """""""""""""""""
168181
169- For the `assertHit ` and `assertMiss ` assertions to work, you need to add a
170- :ref: `custom X-Cache header <nginx_debugging >` to responses served
171- by your Nginx.
172-
173- SymfonyTestCase
174- ---------------
175-
176- This test case helps to test invalidation requests with a symfony application
177- running the Symfony HttpCache and invalidating its cache folder to get reliable
178- tests.
179-
180- The ``SymfonyTestCase `` does automatically start a web server. It is assumed
181- that the web server you run for the application has the HttpCache integrated.
182-
183- Configuration
184- '''''''''''''
182+ It is assumed that the web server you run for the application has the HttpCache
183+ integrated.
185184
186185======================= ========================= ================================================ ===========================================
187186Constant Getter Default Description
@@ -194,59 +193,92 @@ Constant Getter Default
194193 running PHPUnit.
195194======================= ========================= ================================================ ===========================================
196195
197- Enable Assertions
198- '''''''''''''''''
196+ HttpCaller Trait
197+ ~~~~~~~~~~~~~~~~
198+
199+ Provides your tests with a ``getResponse `` method, which retrieves a URI from
200+ your application through a real HTTP call that goes through the HTTP caching
201+ proxy::
199202
200- For the `assertHit ` and `assertMiss ` assertions to work, you need to add debug
201- information in your AppCache. Create the cache kernel with the option
202- ``'debug' => true `` and add the following to your ``AppCache ``::
203+ use FOS\HttpCache\Test\HttpCaller;
203204
204- public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
205+ class YourTest extends \PHPUnit_Framework_TestCase
205206 {
206- $response = parent::handle($request, $type, $catch);
207-
208- if ($response->headers->has('X-Symfony-Cache')) {
209- if (false !== strpos($response->headers->get('X-Symfony-Cache'), 'miss')) {
210- $state = 'MISS';
211- } elseif (false !== strpos($response->headers->get('X-Symfony-Cache'), 'fresh')) {
212- $state = 'HIT';
213- } else {
214- $state = 'UNDETERMINED';
215- }
216- $response->headers->set('X-Cache', $state);
207+ public function testCachingHeaders()
208+ {
209+ // Get some response from your application
210+ $response = $this->getResponse('/path');
211+
212+ // Optionally with request headers and a custom method
213+ $response = $this->getResponse('/path', ['Accept' => 'text/json'], 'PUT');
217214 }
215+ }
218216
219- return $response;
217+ CacheAssertions Trait
218+ ~~~~~~~~~~~~~~~~~~~~~
219+
220+ Provides cache hit/miss assertions to your tests. To enable the these
221+ ``assertHit `` and ``assertMiss `` assertions, you need to configure your caching
222+ server to set an `X-Cache ` header with the cache status:
223+
224+ * :ref: `Varnish <varnish_debugging >`
225+ * :ref: `NGINX <nginx_debugging >`
226+ * :ref: `Symfony HttpCache <symfony-cache x-debugging >`
227+
228+ Then use the assertions as follows::
229+
230+ use FOS\HttpCache\Test\CacheAssertions;
231+
232+ class YourTest extends \PHPUnit_Framework_TestCase
233+ {
234+ public function testCacheHitOrMiss()
235+ {
236+ // Assert the application response is a cache miss
237+ $this->assertMiss($response);
238+
239+ // Or assert it is a hit
240+ $this->assertHit($response);
241+ }
220242 }
221243
222- The ``UNDETERMINED `` state should never happen. If it does, it means that your
223- HttpCache is not correctly set into debug mode.
244+ Base Classes for Convenience
245+ ----------------------------
246+
247+ If you prefer, you can extend your test classes from ``VarnishTestCase ``,
248+ ``NginxTestCase `` or ``SymfonyTestCase ``. The appropriate traits will then
249+ automatically be included.
224250
225251Usage
226252-----
227253
228254This example shows how you can test whether the caching headers your
229- application sets influence Varnish as you expect them to::
255+ application sets influence your caching proxy as you expect them to::
230256
231- use FOS\HttpCache\Test\VarnishTestCase;
257+ use FOS\HttpCache\Test\CacheAssertions;
258+ use FOS\HttpCache\Test\HttpCaller;
259+ use FOS\HttpCache\Test\VarnishTest;
260+ // or FOS\HttpCache\Test\NginxTest;
261+ // or FOS\HttpCache\Test\SymfonyTest;
232262
233- class YourFunctionalTest extends VarnishTestCase
263+ class YourTest extends \PHPUnit_Framework_TestCase
234264 {
235265 public function testCachingHeaders()
236266 {
237- // Varnish is restarted, so you don’t have to worry about previously
238- // cached content. Before continuing, the VarnishTestCase waits for
239- // Varnish to become available.
267+ // The caching proxy is (re)started, so you don’t have to worry
268+ // about previously cached content. Before continuing, the
269+ // VarnishTest/ NginxTest trait waits for the caching proxy to
270+ // become available.
240271
241- // Retrieve an URL from your application
272+ // Retrieve a URL from your application
242273 $response = $this->getResponse('/your/resource');
243274
244275 // Assert the response was a cache miss (came from the backend
245276 // application)
246277 $this->assertMiss($response);
247278
248- // Assume the URL /your/resource sets caching headers. If we retrieve
249- // it again, we should have a cache hit (response delivered by Varnish):
279+ // Assume the URL /your/resource sets caching headers. If we
280+ // retrieve it again, we should have a cache hit (response delivered
281+ // by the caching proxy):
250282 $response = $this->getResponse('/your/resource');
251283 $this->assertHit($response);
252284 }
@@ -255,26 +287,34 @@ application sets influence Varnish as you expect them to::
255287This example shows how you can test whether your application purges content
256288correctly::
257289
258- public function testCachePurge()
290+ use FOS\HttpCache\Test\CacheAssertions;
291+ use FOS\HttpCache\Test\HttpCaller;
292+ use FOS\HttpCache\Test\VarnishTest;
293+ // or FOS\HttpCache\Test\NginxTest;
294+ // or FOS\HttpCache\Test\SymfonyTest;
295+
296+ class YourTest extends \PHPUnit_Framework_TestCase
259297 {
260- // Again, Varnish is restarted, so your test is independent from
261- // other tests
298+ public function testCachePurge()
299+ {
300+ // Again, the caching proxy is restarted, so your test is independent
301+ // from other tests
262302
263- $url = '/blog/articles/1';
303+ $url = '/blog/articles/1';
264304
265- // First request must be a cache miss
266- $this->assertMiss($this->getResponse($url));
305+ // First request must be a cache miss
306+ $this->assertMiss($this->getResponse($url));
267307
268- // Next requests must be a hit
269- $this->assertHit($this->getResponse($url));
308+ // Next requests must be a hit
309+ $this->assertHit($this->getResponse($url));
270310
271- // Purge
272- $this->varnish ->purge('/blog/articles/1');
311+ // Purge
312+ $this->getProxyClient() ->purge('/blog/articles/1');
273313
274- // First request after must again be a miss
275- $this->assertMiss($this->getResponse($url));
314+ // First request after must again be a miss
315+ $this->assertMiss($this->getResponse($url));
316+ }
276317 }
277318
278- Tests for Nginx look the same but extend the NginxTestCase.
279319For more ideas, see this library’s functional tests in the
280320:source: `tests/Functional/ ` directory.
0 commit comments