@@ -4,22 +4,30 @@ Testing Your Application
4
4
========================
5
5
6
6
This 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
21
26
hit/miss.
22
27
28
+ Configuration
29
+ -------------
30
+
23
31
The recommended way to configure the test case is by setting constants
24
32
in your ``phpunit.xml ``. Alternatively, you can override the getter methods.
25
33
@@ -85,89 +93,69 @@ You can override getters in your test class in the following way::
85
93
}
86
94
}
87
95
88
- VarnishTestCase
89
- ---------------
96
+ Traits
97
+ ------
90
98
91
- Configuration
92
- '''''''''''''
99
+ Caching Proxy Server Traits
100
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
93
101
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:
96
103
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.
98
109
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.
100
113
101
- Then set your Varnish configuration (VCL) file. All available configuration
102
- parameters are shown below.
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.
103
121
104
122
======================= ========================= ================================================== ===========================================
105
123
Constant Getter Default Description
106
124
======================= ========================= ================================================== ===========================================
125
+ ``WEB_SERVER_HOSTNAME `` ``getHostName() `` hostname your application can be reached at
107
126
``VARNISH_FILE `` ``getConfigFile() `` your Varnish configuration (VCL) file
108
127
``VARNISH_BINARY `` ``getBinary() `` ``varnishd `` your Varnish binary
109
128
``VARNISH_PORT `` ``getCachingProxyPort() `` ``6181 `` port Varnish listens on
110
129
``VARNISH_MGMT_PORT `` ``getVarnishMgmtPort() `` ``6182 `` Varnish management port
111
130
``VARNISH_CACHE_DIR `` ``getCacheDir() `` ``sys_get_temp_dir() `` + ``/foshttpcache-varnish `` directory to use for cache
112
131
``VARNISH_VERSION `` ``getVarnishVersion() `` ``4 `` installed varnish application version
113
- ``WEB_SERVER_HOSTNAME `` ``getHostName() `` hostname your application can be reached at
114
132
======================= ========================= ================================================== ===========================================
115
133
116
- Enable Assertions
117
- '''''''''''''''''
118
-
119
- For the `assertHit ` and `assertMiss ` assertions to work, you need to add a
120
- :ref: `custom X-Cache header <varnish_debugging >` to responses served
121
- by your Varnish.
122
-
123
- NginxTestCase
124
- -------------
125
-
126
- Configuration
127
- '''''''''''''
128
-
129
- By default, the ``NginxTestCase `` starts and stops the NGINX server for you and
130
- deletes all cached contents. Make sure ``symfony/process `` is available in your
131
- project:
134
+ NginxTest Trait
135
+ """""""""""""""
132
136
133
- .. code-block :: bash
137
+ .. include :: includes/symfony-process.rst
134
138
135
- $ composer require symfony/process
136
-
137
- You have to set your NGINX configuration file. All available configuration
138
- parameters are shown below.
139
+ Then configure the following parameters. The web server hostname and path to
140
+ your NGINX configuration file are required.
139
141
140
142
======================= ========================= ================================================ ===========================================
141
143
Constant Getter Default Description
142
144
======================= ========================= ================================================ ===========================================
145
+ ``WEB_SERVER_HOSTNAME `` ``getHostName() `` hostname your application can be reached at
143
146
``NGINX_FILE `` ``getConfigFile() `` your NGINX configuration file
144
147
``NGINX_BINARY `` ``getBinary() `` ``nginx `` your NGINX binary
145
148
``NGINX_PORT `` ``getCachingProxyPort() `` ``8088 `` port NGINX listens on
146
149
``NGINX_CACHE_PATH `` ``getCacheDir() `` ``sys_get_temp_dir() `` + ``/foshttpcache-nginx `` directory to use for cache
147
150
Must match `proxy_cache_path ` directive in
148
151
your configuration file.
149
- ``WEB_SERVER_HOSTNAME `` ``getHostName() `` hostname your application can be reached at
150
152
======================= ========================= ================================================ ===========================================
151
153
152
- Enable Assertions
153
- '''''''''''''''''
154
+ SymfonyTest Trait
155
+ """""""""""""""""
154
156
155
- For the `assertHit ` and `assertMiss ` assertions to work, you need to add a
156
- :ref: `custom X-Cache header <nginx_debugging >` to responses served
157
- by your Nginx.
158
-
159
- SymfonyTestCase
160
- ---------------
161
-
162
- This test case helps to test invalidation requests with a symfony application
163
- running the Symfony HttpCache and invalidating its cache folder to get reliable
164
- tests.
165
-
166
- The ``SymfonyTestCase `` does automatically start a web server. It is assumed
167
- that the web server you run for the application has the HttpCache integrated.
168
-
169
- Configuration
170
- '''''''''''''
157
+ It is assumed that the web server you run for the application has the HttpCache
158
+ integrated.
171
159
172
160
======================= ========================= ================================================ ===========================================
173
161
Constant Getter Default Description
@@ -180,59 +168,92 @@ Constant Getter Default
180
168
running PHPUnit.
181
169
======================= ========================= ================================================ ===========================================
182
170
183
- Enable Assertions
184
- '''''''''''''''''
171
+ HttpCaller Trait
172
+ ~~~~~~~~~~~~~~~~
173
+
174
+ Provides your tests with a ``getResponse `` method, which retrieves a URI from
175
+ your application through a real HTTP call that goes through the HTTP caching
176
+ proxy::
185
177
186
- For the `assertHit ` and `assertMiss ` assertions to work, you need to add debug
187
- information in your AppCache. Create the cache kernel with the option
188
- ``'debug' => true `` and add the following to your ``AppCache ``::
178
+ use FOS\HttpCache\Test\HttpCaller;
189
179
190
- public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
180
+ class YourTest extends \PHPUnit_Framework_TestCase
191
181
{
192
- $response = parent::handle($request, $type, $catch);
193
-
194
- if ($response->headers->has('X-Symfony-Cache')) {
195
- if (false !== strpos($response->headers->get('X-Symfony-Cache'), 'miss')) {
196
- $state = 'MISS';
197
- } elseif (false !== strpos($response->headers->get('X-Symfony-Cache'), 'fresh')) {
198
- $state = 'HIT';
199
- } else {
200
- $state = 'UNDETERMINED';
201
- }
202
- $response->headers->set('X-Cache', $state);
182
+ public function testCachingHeaders()
183
+ {
184
+ // Get some response from your application
185
+ $response = $this->getResponse('/path');
186
+
187
+ // Optionally with request headers and a custom method
188
+ $response = $this->getResponse('/path', ['Accept' => 'text/json'], 'PUT');
203
189
}
190
+ }
191
+
192
+ CacheAssertions Trait
193
+ ~~~~~~~~~~~~~~~~~~~~~
194
+
195
+ Provides cache hit/miss assertions to your tests. To enable the these
196
+ ``assertHit `` and ``assertMiss `` assertions, you need to configure your caching
197
+ server to set an `X-Cache ` header with the cache status:
204
198
205
- return $response;
199
+ * :ref: `Varnish <varnish_debugging >`
200
+ * :ref: `NGINX <nginx_debugging >`
201
+ * :ref: `Symfony HttpCache <symfony-cache x-debugging >`
202
+
203
+ Then use the assertions as follows::
204
+
205
+ use FOS\HttpCache\Test\CacheAssertions;
206
+
207
+ class YourTest extends \PHPUnit_Framework_TestCase
208
+ {
209
+ public function testCacheHitOrMiss()
210
+ {
211
+ // Assert the application response is a cache miss
212
+ $this->assertMiss($response);
213
+
214
+ // Or assert it is a hit
215
+ $this->assertHit($response);
216
+ }
206
217
}
207
218
208
- The ``UNDETERMINED `` state should never happen. If it does, it means that your
209
- HttpCache is not correctly set into debug mode.
219
+ Base Classes for Convenience
220
+ ----------------------------
221
+
222
+ If you prefer, you can extend your test classes from ``VarnishTestCase ``,
223
+ ``NginxTestCase `` or ``SymfonyTestCase ``. The appropriate traits will then
224
+ automatically be included.
210
225
211
226
Usage
212
227
-----
213
228
214
229
This example shows how you can test whether the caching headers your
215
- application sets influence Varnish as you expect them to::
230
+ application sets influence your caching proxy as you expect them to::
216
231
217
- use FOS\HttpCache\Test\VarnishTestCase;
232
+ use FOS\HttpCache\Test\CacheAssertions;
233
+ use FOS\HttpCache\Test\HttpCaller;
234
+ use FOS\HttpCache\Test\VarnishTest;
235
+ // or FOS\HttpCache\Test\NginxTest;
236
+ // or FOS\HttpCache\Test\SymfonyTest;
218
237
219
- class YourFunctionalTest extends VarnishTestCase
238
+ class YourTest extends \PHPUnit_Framework_TestCase
220
239
{
221
240
public function testCachingHeaders()
222
241
{
223
- // Varnish is restarted, so you don’t have to worry about previously
224
- // cached content. Before continuing, the VarnishTestCase waits for
225
- // Varnish to become available.
242
+ // The caching proxy is (re)started, so you don’t have to worry
243
+ // about previously cached content. Before continuing, the
244
+ // VarnishTest/ NginxTest trait waits for the caching proxy to
245
+ // become available.
226
246
227
- // Retrieve an URL from your application
247
+ // Retrieve a URL from your application
228
248
$response = $this->getResponse('/your/resource');
229
249
230
250
// Assert the response was a cache miss (came from the backend
231
251
// application)
232
252
$this->assertMiss($response);
233
253
234
- // Assume the URL /your/resource sets caching headers. If we retrieve
235
- // it again, we should have a cache hit (response delivered by Varnish):
254
+ // Assume the URL /your/resource sets caching headers. If we
255
+ // retrieve it again, we should have a cache hit (response delivered
256
+ // by the caching proxy):
236
257
$response = $this->getResponse('/your/resource');
237
258
$this->assertHit($response);
238
259
}
@@ -241,26 +262,34 @@ application sets influence Varnish as you expect them to::
241
262
This example shows how you can test whether your application purges content
242
263
correctly::
243
264
244
- public function testCachePurge()
265
+ use FOS\HttpCache\Test\CacheAssertions;
266
+ use FOS\HttpCache\Test\HttpCaller;
267
+ use FOS\HttpCache\Test\VarnishTest;
268
+ // or FOS\HttpCache\Test\NginxTest;
269
+ // or FOS\HttpCache\Test\SymfonyTest;
270
+
271
+ class YourTest extends \PHPUnit_Framework_TestCase
245
272
{
246
- // Again, Varnish is restarted, so your test is independent from
247
- // other tests
273
+ public function testCachePurge()
274
+ {
275
+ // Again, the caching proxy is restarted, so your test is independent
276
+ // from other tests
248
277
249
- $url = '/blog/articles/1';
278
+ $url = '/blog/articles/1';
250
279
251
- // First request must be a cache miss
252
- $this->assertMiss($this->getResponse($url));
280
+ // First request must be a cache miss
281
+ $this->assertMiss($this->getResponse($url));
253
282
254
- // Next requests must be a hit
255
- $this->assertHit($this->getResponse($url));
283
+ // Next requests must be a hit
284
+ $this->assertHit($this->getResponse($url));
256
285
257
- // Purge
258
- $this->varnish ->purge('/blog/articles/1');
286
+ // Purge
287
+ $this->getProxyClient() ->purge('/blog/articles/1');
259
288
260
- // First request after must again be a miss
261
- $this->assertMiss($this->getResponse($url));
289
+ // First request after must again be a miss
290
+ $this->assertMiss($this->getResponse($url));
291
+ }
262
292
}
263
293
264
- Tests for Nginx look the same but extend the NginxTestCase.
265
294
For more ideas, see this library’s functional tests in the
266
295
:source: `tests/Functional/ ` directory.
0 commit comments