Skip to content

Commit c079456

Browse files
committed
update to tell PHPUnit assertions stopped working
resolve Behat/Behat#1618
1 parent 1f13e84 commit c079456

File tree

2 files changed

+92
-27
lines changed

2 files changed

+92
-27
lines changed

quick_start.rst

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -455,49 +455,46 @@ code we could come up with to fulfil our scenario. Something like this:
455455
#[Then('I should have :arg1 product(s) in the basket')]
456456
public function iShouldHaveProductInTheBasket($count)
457457
{
458-
// Normally you would import this class - we are using the fully qualified name
459-
// to highlight that Behat does not come with an assertion tool (see note below).
460-
\PHPUnit\Framework\Assert::assertCount(
461-
intval($count),
462-
$this->basket
463-
);
458+
if (count($this->basket) !== intval($count)) {
459+
throw new \Exception(
460+
sprintf(
461+
'The basket should have %d item(s), but it has %d.',
462+
intval($count),
463+
count($this->basket)
464+
)
465+
);
466+
}
464467
}
465468
466469
#[Then('the overall basket price should be £:arg1')]
467470
public function theOverallBasketPriceShouldBePs($price)
468471
{
469-
\PHPUnit\Framework\Assert::assertSame(
470-
floatval($price),
471-
$this->basket->getTotalPrice()
472-
);
472+
$expectedPrice = floatval($price);
473+
$actualPrice = $this->basket->getTotalPrice();
474+
475+
if ($expectedPrice !== $actualPrice) {
476+
throw new \Exception(
477+
sprintf(
478+
'Expected basket total price to be %s, but got %s.',
479+
$expectedPrice,
480+
$actualPrice
481+
)
482+
);
483+
}
473484
}
474485
}
475486
476487
As you can see, in order to test and implement our application, we introduced 2 objects -
477488
``Shelf`` and ``Basket``. The first is responsible for storing products and their prices,
478489
the second is responsible for the representation of our customer basket. Through appropriate step
479490
definitions we declare products' prices and add products to the basket. We then compare the
480-
state of our ``Basket`` object with our expectations using PHPUnit assertions.
491+
state of our ``Basket`` object with our expectations and throw exception if the expectations aren't met.
481492

482493
.. note::
483494

484495
Behat doesn't come with its own assertion tool, but you can use any proper assertion
485-
tool out there. A proper assertion tool is a library whose assertions throw
486-
exceptions on failure. For example, if you're familiar with PHPUnit you can use
487-
its assertions in Behat by installing it via composer:
488-
489-
.. code-block:: bash
490-
491-
$ php composer.phar require --dev phpunit/phpunit
492-
493-
and then by simply using assertions in your steps:
494-
495-
.. code-block:: php
496-
497-
\PHPUnit\Framework\Assert::assertCount(
498-
intval($count),
499-
$this->basket
500-
);
496+
tool out there.
497+
Learn more about :ref:`assertion-tools`.
501498

502499
Now try to execute your feature tests:
503500

useful_resources.rst

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,74 @@ Integrating Behat with PHPStorm
1818
More information on integrating Behat with PHPStorm can be found in this
1919
`blog post`_.
2020

21+
.. _assertion-tools:
22+
23+
Assertion tools
24+
---------------
25+
26+
A proper assertion tool is a library whose assertions throw exceptions on failure.
27+
28+
For example a list of the most known:
29+
30+
- https://github.com/webmozarts/assert
31+
- https://github.com/beberlei/assert
32+
- https://github.com/zenstruck/assert
33+
34+
.. caution::
35+
If you are familiar with PHPUnit, you can use its assertion library
36+
.. code-block:: bash
37+
38+
$ php composer.phar require --dev phpunit/phpunit
39+
40+
and then by simply using assertions in your steps:
41+
42+
.. code-block:: php
43+
44+
\PHPUnit\Framework\Assert::assertCount(
45+
intval($count),
46+
$this->basket
47+
);
48+
49+
**WARNING: using PHPUnit for assertions no longer works with PHP 11.3.0 and later out-of-the-box**.
50+
51+
This is due to a change in how PHPUnit's internal components are initialized. There are two options
52+
to make PHPUnit assertions work with PHPUnit 11.3:
53+
54+
**Recommended:** bootstrap PHPUnit during Behat execution from a `BeforeSuite` hook. This initializes
55+
PHPUnit only for Behat runs and is less brittle:
56+
57+
.. code-block:: php
58+
59+
use Behat\Hook\BeforeSuite;
60+
61+
class FeatureContext {
62+
63+
#[BeforeSuite]
64+
public static function initPhpunit() {
65+
(new \PHPUnit\TextUI\Configuration\Builder())->build([]);
66+
}
67+
}
68+
69+
If you have multiple suites, you may want to use a static variable in the hook to ensure the initialization only
70+
runs once.
71+
72+
**Alternative:** add an explicit bootstrap call to your project's PHPUnit bootstrap file (for example,
73+
`tests/bootstrap.php` in Symfony).
74+
75+
.. code-block:: php
76+
77+
if (defined('BEHAT_BIN_PATH')) {
78+
(new \PHPUnit\TextUI\Configuration\Builder())->build([]);
79+
}
80+
81+
This approach can be more convenient if your project contains many context classes
82+
and you prefer centralizing the setup in a single location, however it relies on the `BEHAT_BIN_PATH` constant
83+
which is not part of Behat's public API and may be removed or changed in future releases,
84+
so it is a less robust approach.
85+
86+
Learn more at https://github.com/Behat/Behat/issues/1618.
87+
88+
2189
Behat cheat sheet
2290
-----------------
2391

0 commit comments

Comments
 (0)