Skip to content

Commit ab4bfe5

Browse files
committed
Merge branch '2.8' into 3.0
2 parents 41393d9 + 8e59931 commit ab4bfe5

File tree

4 files changed

+252
-1
lines changed

4 files changed

+252
-1
lines changed

components/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ The Components
2323
http_kernel/index
2424
intl
2525
options_resolver
26+
phpunit_bridge
2627
process
2728
property_access/index
2829
routing/index

components/map.rst.inc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* :doc:`/components/asset/introduction`
66

77
* :doc:`/components/browser_kit/index`
8-
8+
99
* :doc:`/components/browser_kit/introduction`
1010

1111
* :doc:`/components/class_loader/index`
@@ -116,6 +116,10 @@
116116

117117
* :doc:`/components/options_resolver`
118118

119+
* **PHPUnitBridge**
120+
121+
* :doc:`/components/phpunit_bridge`
122+
119123
* **Process**
120124

121125
* :doc:`/components/process`

components/phpunit_bridge.rst

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
.. index::
2+
single: PHPUnitBridge
3+
single: Components; PHPUnitBridge
4+
5+
The PHPUnit Bridge
6+
==================
7+
8+
The PHPUnit Bridge provides utilities to report legacy tests and usage of
9+
deprecated code and a helper for time-sensitive tests.
10+
11+
It comes with the following features:
12+
13+
* Forces the tests to use a consistent locale (``C``);
14+
15+
* Auto-register ``class_exists`` to load Doctrine annotations (when used);
16+
17+
* It displays the whole list of deprecated features used in the application;
18+
19+
* Displays the stack trace of a deprecation on-demand;
20+
21+
* Provides a ``ClockMock`` helper class for time-sensitive tests.
22+
23+
.. versionadded:: 2.7
24+
The PHPUnit Bridge was introduced in Symfony 2.7. It is however possible to
25+
install the bridge in any Symfony application (even 2.3).
26+
27+
Installation
28+
------------
29+
30+
You can install the component in 2 different ways:
31+
32+
* :doc:`Install it via Composer </components/using_components>`
33+
(``symfony/phpunit-bridge`` on `Packagist`_); as a dev dependency;
34+
35+
* Use the official Git repository (https://github.com/symfony/phpunit-bridge).
36+
37+
.. include:: /components/require_autoload.rst.inc
38+
39+
Usage
40+
-----
41+
42+
Once the component installed, it automatically registers a
43+
`PHPUnit event listener`_ which in turn registers a `PHP error handler`_
44+
called :class:`Symfony\\Bridge\\PhpUnit\\DeprecationErrorHandler`. After
45+
running your PHPUnit tests, you will get a report similar to this one:
46+
47+
.. image:: /images/components/phpunit_bridge/report.png
48+
49+
The summary includes:
50+
51+
**Unsilenced**
52+
Reports deprecation notices that were triggered without the recommended
53+
`@-silencing operator`_.
54+
55+
**Legacy**
56+
Deprecation notices denote tests that explicitly test some legacy features.
57+
58+
**Remaining/Other**
59+
Deprecation notices are all other (non-legacy) notices, grouped by message,
60+
test class and method.
61+
62+
Trigger Deprecation Notices
63+
---------------------------
64+
65+
Deprecation notices can be triggered by using::
66+
67+
@trigger_error('Your deprecation message', E_USER_DEPRECATED);
68+
69+
Without the `@-silencing operator`_, users would need to opt-out from deprecation
70+
notices. Silencing by default swaps this behavior and allows users to opt-in
71+
when they are ready to cope with them (by adding a custom error handler like the
72+
one provided by this bridge). When not silenced, deprecation notices will appear
73+
in the **Unsilenced** section of the deprecation report.
74+
75+
Mark Tests as Legacy
76+
--------------------
77+
78+
There are four ways to mark a test as legacy:
79+
80+
* (**Recommended**) Add the ``@group legacy`` annotation to its class or method;
81+
82+
* Make its class name start with the ``Legacy`` prefix;
83+
84+
* Make its method name start with ``testLegacy`` instead of ``test``;
85+
86+
* Make its data provider start with ``provideLegacy`` or ``getLegacy``.
87+
88+
Configuration
89+
-------------
90+
91+
In case you need to inspect the stack trace of a particular deprecation
92+
triggered by your unit tests, you can set the ``SYMFONY_DEPRECATIONS_HELPER``
93+
`environment variable`_ to a regular expression that matches this deprecation's
94+
message, enclosed with ``/``. For example, with:
95+
96+
.. code-block:: xml
97+
98+
<!-- http://phpunit.de/manual/4.1/en/appendixes.configuration.html -->
99+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
100+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
101+
>
102+
103+
<!-- ... -->
104+
105+
<php>
106+
<server name="KERNEL_DIR" value="app/" />
107+
<env name="SYMFONY_DEPRECATIONS_HELPER" value="/foobar/" />
108+
</php>
109+
</phpunit>
110+
111+
PHPUnit_ will stop your test suite once a deprecation notice is triggered whose
112+
message contains the ``"foobar"`` string.
113+
114+
Making Tests Fail
115+
-----------------
116+
117+
By default, any non-legacy-tagged or any non-`@-silenced`_ deprecation notices will
118+
make tests fail. Alternatively, setting ``SYMFONY_DEPRECATIONS_HELPER`` to an
119+
arbitrary value (ex: ``320``) will make the tests fails only if a higher number
120+
of deprecation notices is reached (``0`` is the default value). You can also set
121+
the value ``"weak"`` which will make the bridge ignore any deprecation notices.
122+
This is useful to projects that must use deprecated interfaces for backward
123+
compatibility reasons.
124+
125+
Time-sensitive Tests
126+
--------------------
127+
128+
Use Case
129+
~~~~~~~~
130+
131+
If you have this kind of time-related tests::
132+
133+
use Symfony\Component\Stopwatch\Stopwatch;
134+
135+
class MyTest extends \PHPUnit_Framework_TestCase
136+
{
137+
public function testSomething()
138+
{
139+
$stopwatch = new Stopwatch();
140+
141+
$stopwatch->start();
142+
sleep(10);
143+
$duration = $stopwatch->stop();
144+
145+
$this->assertEquals(10, $duration);
146+
}
147+
}
148+
149+
You used the :doc:`Symfony Stopwatch Component </components/stopwatch>` to
150+
calculate the duration time of your process, here 10 seconds. However, depending
151+
on the load of the server your the processes running on your local machine, the
152+
``$duration`` could for example be `10.000023s` instead of `10s`.
153+
154+
This kind of tests are called transient tests: they are failing randomly
155+
depending on spurious and external circumstances. They are often cause trouble
156+
when using public continuous integration services like `Travis CI`_.
157+
158+
Clock Mocking
159+
~~~~~~~~~~~~~
160+
161+
The :class:`Symfony\\Bridge\\PhpUnit\\ClockMock` class provided by this bridge
162+
allows you to mock the PHP's built-in time functions ``time()``,
163+
``microtime()``, ``sleep()`` and ``usleep()``.
164+
165+
To use the ``ClockMock`` class in your test, you can:
166+
167+
* (**Recommended**) Add the ``@group time-sensitive`` annotation to its class or
168+
method;
169+
170+
* Register it manually by calling ``ClockMock::register(__CLASS__)`` and
171+
``ClockMock::withClockMock(true)`` before the test and
172+
``ClockMock::withClockMock(false)`` after the test.
173+
174+
As a result, the following is guarenteed to work and is no longer a transient
175+
test::
176+
177+
use Symfony\Component\Stopwatch\Stopwatch;
178+
179+
/**
180+
* @group time-sensitive
181+
*/
182+
class MyTest extends \PHPUnit_Framework_TestCase
183+
{
184+
public function testSomething()
185+
{
186+
$stopwatch = new Stopwatch();
187+
188+
$stopwatch->start();
189+
sleep(10);
190+
$duration = $stopwatch->stop();
191+
192+
$this->assertEquals(10, $duration);
193+
}
194+
}
195+
196+
And that's all!
197+
198+
.. tip::
199+
200+
An added bonus of using the ``ClockMock`` class is that time passes
201+
instantly. Using PHP's ``sleep(10)`` will make your test wait for 10
202+
actual seconds (more or less). In contrast, the ``ClockMock`` class
203+
advances the internal clock the given number of seconds without actually
204+
waiting that time, so your test will execute 10 seconds faster.
205+
206+
Troubleshooting
207+
~~~~~~~~~~~~~~~
208+
209+
The ``@group time-sensitive`` works "by convention" and assumes that the
210+
namespace of the tested class can be obtained just by removing the ``\Tests\``
211+
part from the test namespace. I.e. that if the your test case fully-qualified
212+
class name (FQCN) is ``App\Tests\Watch\DummyWatchTest``, it assumes the tested
213+
class FQCN is ``App\Watch\DummyWatch``.
214+
215+
If this convention doesn't work for your application, you can also configure
216+
the mocked namespaces in the ``phpunit.xml`` file, as done for example in the
217+
:doc:`HttpKernel Component </components/http_kernel/introduction>`:
218+
219+
.. code-block:: xml
220+
221+
<!-- http://phpunit.de/manual/4.1/en/appendixes.configuration.html -->
222+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
223+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
224+
>
225+
226+
<!-- ... -->
227+
228+
<listeners>
229+
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
230+
<arguments>
231+
<array>
232+
<element><string>Symfony\Component\HttpFoundation</string></element>
233+
</array>
234+
</arguments>
235+
</listener>
236+
</listeners>
237+
</phpunit>
238+
239+
.. _PHPUnit: https://phpunit.de
240+
.. _`PHPUnit event listener`: https://phpunit.de/manual/current/en/extending-phpunit.html#extending-phpunit.PHPUnit_Framework_TestListener
241+
.. _`PHP error handler`: http://php.net/manual/en/book.errorfunc.php
242+
.. _`environment variable`: https://phpunit.de/manual/current/en/appendixes.configuration.html#appendixes.configuration.php-ini-constants-variables
243+
.. _Packagist: https://packagist.org/packages/symfony/phpunit-bridge
244+
.. _`@-silencing operator`: http://php.net/manual/en/language.operators.errorcontrol.php
245+
.. _`@-silenced`: http://php.net/manual/en/language.operators.errorcontrol.php
246+
.. _`Travis CI`: https://travis-ci.com/
46.6 KB
Loading

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy