Lucky you! You found an early release chapter - it will be fully polished and published shortly!
Rest assured, the gnomes are hard at work
completing this video!
Let's make this test real with data and assertions.
There are two main ways to do assertions with Browser. First, it comes with a bunch
of built-in methods to help, like ->assertJson()
. Or... you can always just grab
the JSON that comes back from an endpoint and check things using the built-in
PHPUnit assertions you know and love. We'll see both.
Let's start by checking ->assertJson()
. When we run that:
symfony php bin/phpunit
It passes! Cool! We know that this response should have a hydra:totalItems
property set to the number of results. Right now, our database is empty... but we
can at least assert that it matches zero.
To do that, use ->assertJsonMatches()
. This is a special method from Browser that
uses a special syntax that allows us to read different parts off the JSON. We'll
dig into it in a minute.
But this one is simple: assert that hydra:totalItems
equals 0
.
When we try this:
symfony php bin/phpunit
It fails! But with a great error:
mtdowling/jmespath.php
is required to search JSON
Ah, we need to install that! Copy the composer require
line, find your terminal,
and run it:
composer require mtdowling/jmespath.php --dev
This "JMESPath" thing is actually super cool: it's a "query language" for reading
different parts of any JSON. For example, if this is your JSON and you want to
read the a
key, just say a
. Simple.
But you can also do deeper, like: a.b.c.d
. Or, get crazier: grab the 1
index, or grab a.b.c
, then the 0
index, .d
, the 1
index then the 0
index. You can even slice the array in different ways. Basically... you can go
nuts.
But we're not going to lose our minds with this. It's a handy syntax... but if things get too complex, we can always test the JSON manually, which we'll do in a bit.
Anyway, now that we have the library installed, let's run the test again.
symfony php bin/phpunit
It still fails! With a weird error:
Syntax error at character 5
hydra:totalItems
.
Unfortunately, the :
is a special character inside of JMESPath. So
whenever we have a :
, we need to put quotes around that key.
Not ideal, but not a huge inconvenience.
Now when we try it:
symfony php bin/phpunit
It passes!
But... this isn't a very interesting test: we're just asserting that we get nothing back... because the database is empty. To make our test real, we need data: we need to seed the database with data at the start of the test.
Fortunately, Foundry makes that dead-simple. At the top, call
DragonTreasureFactory::createMany()
and let's create 5 treasures. Now, below,
assert that we get 5 results. It's just that simple. And actually, let me put
our dump back so we can see the result.
Try it now:
symfony php bin/phpunit
It passes! And if you look up, yea! The response has 5 treasures! Dang, that was easy.
Next: let's use JMESPath to assert something more challenging. Then we'll back up and see how we can dig into Browser to give us infinite flexibility - and simplicity - when it comes to testing JSON.
"Houston: no signs of life"
Start the conversation!
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^3.0", // v3.1.2
"doctrine/annotations": "^2.0", // 2.0.1
"doctrine/doctrine-bundle": "^2.8", // 2.8.3
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
"doctrine/orm": "^2.14", // 2.14.1
"nelmio/cors-bundle": "^2.2", // 2.2.0
"nesbot/carbon": "^2.64", // 2.66.0
"phpdocumentor/reflection-docblock": "^5.3", // 5.3.0
"phpstan/phpdoc-parser": "^1.15", // 1.16.1
"symfony/asset": "6.2.*", // v6.2.5
"symfony/console": "6.2.*", // v6.2.5
"symfony/dotenv": "6.2.*", // v6.2.5
"symfony/expression-language": "6.2.*", // v6.2.5
"symfony/flex": "^2", // v2.2.4
"symfony/framework-bundle": "6.2.*", // v6.2.5
"symfony/property-access": "6.2.*", // v6.2.5
"symfony/property-info": "6.2.*", // v6.2.5
"symfony/runtime": "6.2.*", // v6.2.5
"symfony/security-bundle": "6.2.*", // v6.2.6
"symfony/serializer": "6.2.*", // v6.2.5
"symfony/twig-bundle": "6.2.*", // v6.2.5
"symfony/ux-react": "^2.6", // v2.7.1
"symfony/ux-vue": "^2.7", // v2.7.1
"symfony/validator": "6.2.*", // v6.2.5
"symfony/webpack-encore-bundle": "^1.16", // v1.16.1
"symfony/yaml": "6.2.*" // v6.2.5
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
"mtdowling/jmespath.php": "^2.6", // 2.6.1
"phpunit/phpunit": "^9.5", // 9.6.3
"symfony/browser-kit": "6.2.*", // v6.2.5
"symfony/css-selector": "6.2.*", // v6.2.5
"symfony/debug-bundle": "6.2.*", // v6.2.5
"symfony/maker-bundle": "^1.48", // v1.48.0
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/phpunit-bridge": "^6.2", // v6.2.5
"symfony/stopwatch": "6.2.*", // v6.2.5
"symfony/web-profiler-bundle": "6.2.*", // v6.2.5
"zenstruck/browser": "^1.2", // v1.2.0
"zenstruck/foundry": "^1.26" // v1.28.0
}
}