Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

Functional Tests

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

The last type of test is called a functional test. And it's way different than what we've seen so far. With unit and integration tests, we call methods on our code and test the output. But with a functional test, you command a browser, which surfs to your site, clicks on links, fills out forms and asserts things it sees on the page. Yep, you're testing the interface that your users actually use.

Oh, and functional tests also apply if you're building an API. It's the same idea: you would use an HTTP client to make real HTTP requests to your API and assert the output.


First, to give us some magic, I want to install a special bundle: Google for LiipFunctionalTestBundle.

This bundle is not needed to write functional tests. But, it has a collection of optional, extra goodies!

Copy the composer require line, move over to your terminal, and paste:

composer require --dev "liip/functional-test-bundle:^1.9"


If you are using PHPUnit 7+ or Symfony 4+, you need to require a newer version of this bundle. To install it, run the next command without the specific version constraint: composer require --dev liip/functional-test-bundle

Functional Test Setup

Functional tests look like unit tests at first: they use PHPUnit in the exact way we've been seeing. But instead of writing one test class per PHP class, you'll usually create one test class per controller class.

It doesn't have much yet, but we're going to functionally test our homepage. Since the code behind this lives in DefaultController, let's create a Controller directory in tests and add a new DefaultControllerTest class.

But now, instead of extending TestCase or KernelTestCase, extend WebTestCase. But wait! There are two! The normal base class is the one from FrameworkBundle. It actually extends KernelTestCase, which means we have all the same tools as integration tests. But, it adds a few methods to help create a client object: a special object we'll use to make requests into our app.

Today we'll choose WebTestCase from LiipFunctionalTestBundle. No surprise, this class itself extends the normal WebTestCase. Then, it adds a bunch of optional magic.

... lines 1 - 4
use Liip\FunctionalTestBundle\Test\WebTestCase;
class DefaultControllerTest extends WebTestCase
... lines 9 - 16

TDD & The Functional Test

Let's add the first test: public function testEnclosuresAreShownOnTheHomepage(). Right now, the homepage is empty. But in a minute, we're going to render all of the enclosures. So let's do a little TDD testing! Start by creating a client with $client = $this->makeClient(). This method comes from LiipFunctionalTestBundle, but is just a wrapper around Symfony's normal static::createClient(). The version from the bundle just adds some optional authentication magic.

... lines 1 - 6
class DefaultControllerTest extends WebTestCase
public function testEnclosuresAreShownOnHomepage()
... line 10
$client = $this->makeClient();
... lines 12 - 15

Next, make a request! $crawler = $client->request('GET', '/') to go to the homepage. We'll talk more about this Crawler object in a few minutes. Then, the simplest test is to say $this->assertStatusCode(200) and pass $client. But even this is just a shortcut to make sure 200 matches $client->getResponse()->getStatusCode().

... lines 1 - 8
public function testEnclosuresAreShownOnHomepage()
... lines 10 - 12
$crawler = $client->request('GET', '/');
$this->assertStatusCode(200, $client);
... lines 17 - 18

And yea... the first part of the test is done! This at least makes sure our page isn't broken!

Finishing Installing LiipFunctionalTestBundle

But before we try it, we need to finish installing the bundle. Copy the 3 bundle lines, open AppKernel and paste them there.

... lines 1 - 6
class AppKernel extends Kernel
public function registerBundles()
... lines 11 - 21
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
... lines 23 - 31
if ('test' === $this->getEnvironment()) {
$bundles[] = new LiipFunctionalTestBundle();
... lines 36 - 37
... lines 39 - 58

We also need to add one line to config_test.yml.

... lines 1 - 27
liip_functional_test: ~

If you're using Symfony Flex, these steps should eventually be done for you. I say eventually, because - at this moment - Symfony 4 support is still being added to the bundle.

Ok! Let's try it! Find your terminal, run phpunit, and point it at the new controller:

./vendor/bin/phpunit tests/AppBundle/Controller/DefaultControllerTest.php

Yes! It passes!

Symfony's Client Versus Mink Versus Others

But... what just happened exactly? Did our code just make a real HTTP request to our app... just like if we refreshed it in the browser? Well... not quite.

Remember: in a functional test, we use PHP to command a browser and tell it to go to a page, click on links and fill out forms. But, there are multiple libraries that give us this superpower. We're using Symfony's BrowserKit client... mostly because it's built into Symfony and easy to start using. But, there are others. My favorite is called Mink, which is used behind the scenes with Behat. We have a tutorial all about Behat, with big sections devoted to Mink. So, check that out.

Go Deeper!

Learn all about Mink and Behat: https://knpuniversity.com/screencast/behat

So... what's the difference between Symfony's BrowserKit and Mink? With BrowserKit, you're not actually making a real HTTP request to your app. Nope, you're making a "fake" request directly into your code. Honestly, that doesn't matter much. And actually, it makes setup a bit easier: we didn't need to configure that our site lived at http://localhost:8000 or anything like that.

But, BrowserKit has one big disadvantage: you can't test JavaScript functionality. Nope, since these are fake requests, your JavaScript simply doesn't run! This is the main reason why I prefer Mink: it does allow you to run your code in a real browser... with JavaScript.

For the next few chapters, we are going to use Symfony's BrowserKit Client. But, most of the concepts transfer well to other test clients, like Mink. And you'll still be able to use most of the magic from LiipFuntionalTestBundle. If you have questions about this, just ask in the comments!

Next, let's talk about this $crawler object and how we can use it to dive into the HTML of the page!

Leave a comment!

Login or Register to join the conversation

Hello guys,

in case you are using Symfony 3.3 and PHPUnit 7 or later (the version that will be installed if you follow this tutorial at this moment), you may end in a limbo of compatibility with liip. Make sure you are using the same version of PHPUnit that this tutorial is using, the version 6.3. Then you won't have any problem installing liip.


1 Reply

Hey fahani ! Thanks again for reporting this issue, we've updated the script and added a note to the video. You rock! 👏


Hey fahani!

Thanks for the pointer on this! We'll look into adding a note so other people don't hit this :).


Cameron Avatar
Cameron Avatar Cameron | posted 2 years ago | edited

It seems there's an error with test-created "fixtures"/objects (like $user) when I run $this->manager-remove($user); but only when I run the following twice (prior to $this->manager->remove() being called in tearDown() - where the acctual error is triggered):

$crawler = $this->client->request($method, $this->url, $json);

the error follows (once remove() is called):

<blockquote>1) App\Tests\Service\SecurityTest::verifyAccountTwiceError
Doctrine\ORM\ORMInvalidArgumentException: Detached entity 790 cannot be removed

It's fine if I don't try to run request() a second time, but when I try $this->manager->remove($user) it throws this error. Very strange!

My research led me to this related SO question:

The manager is retrieved like this (in setUp()):

$this->manager = $client->getKernel()->getContainer()

Otherwise, I'm starting to like creating tests, they are the first tests I've built for a project, but there's definnitely some challenges.

If anyone has some ideas, I would love to know what's going on.


Hey Cameron,

You definitely should not call remove() method twice for the same object. If the object was already removed - Doctrine will throw an error saying that it cannot delete it (that makes sense, it was deleted before). So, just make sure you call that remove() only once for each entity you want to remove in the system.

> I'm starting to like creating tests, they are the first tests I've built for a project, but there's definnitely some challenges.

Congrats with your first steps! Writing tests will definitely worth it later when you will need to upgrade, add new or change existent features :)


Cameron Avatar

Hi Victor, thanks for the response.

Remove is not being called twice, it's: $this->client->request(...) that is being called twice - but it's the $manager->remove() that triggers the error. Calling $this->client->request(...) twice is the only time I get the error, when I use it once per method callin remove() (later on) does not trigger this problem).

Is there some type of issue with making 2 "http" calls in one test method? Or maybe there's something I've overlooked?


Hey Cameron,

Hm, could you show the code, please? Well, sometimes you have to run $manager->refresh($entity) if you did any modifications to the object and want to have a fresh data in it. Try to add that refresh($entity) call before the logic that checks if the entity should be deleted or no, this should help I think.

I hope this helps!


Nayte91 Avatar
Nayte91 Avatar Nayte91 | posted 3 years ago

Hi there,

I'm struggling with the installation of the liip/functional-test-bundle, composer doesn't seems to want to install anymore this package on the symfony version you deliver with this course; I just downloaded your course, made a composer install and followed the 22 previous chapter religiously, without installing anything fancy.

Tell me if this works well for you, but maybe a fresh version of the code on symfony 4 or 5 would be fast to do for you, and changes barely anything in the course :)

Because overall, "testing with a bite" is excellent : the subject is one of the most important in coding, the dino-project is totally fun, the chapters are perfectly designed, the girl voice-acting here is lovely, everything is fine, so I would love to continue over chapter 23 !


Hey Julien R.!

Nice to chat with you and sorry for the troubles! Let's see if we can work it out :).

composer doesn't seems to want to install anymore this package on the symfony version you deliver with this course

Hmm, yes, I think I see the issue. The latest version of the bundle doesn't support the Symfony version I'm using. You can fix that (for the purpose of this tutorial) by forcing an older version. We actually have a note about this in the tutorial - have you tried this command?

composer require --dev liip/functional-test-bundle:^1.9

Let me know :). If you DID and you got an error, then I definitely want to know about it!

Because overall, "testing with a bite" is excellent : the subject is one of the most important in coding, the dino-project is totally fun, the chapters are perfectly designed, the girl voice-acting here is lovely, everything is fine, so I would love to continue over chapter 23 !

❤️ I'll pass that feedback to the team. And sorry again for the issue :).


Nayte91 Avatar
Nayte91 Avatar Nayte91 | weaverryan | posted 3 years ago | edited

Hello Ryan !

Thank you for taking time chatting with me :)

OK I spend an hour making tests in every possible ways.

To be sure, I Tried with my actual following-the-tutorial-folder, and a brand new install of your code-phpunit.zip --> start folder, and with various PHP versions.

First of all, on the fresh install, I noticed that the PHP version matters.

A composer install with some versions of PHP :

7.2.31 OK
7.3.19 OK
7.4.7 NOK

λ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Your requirements could not be resolved to an installable set of packages.

Problem 1

- This package requires php ^7.0, <7.4 but your PHP version (7.4.7) does not satisfy that requirement.`

As I don't want to test the liip bundle with every PHP versions, so I will continue with PHP 7.3.19 and my composer version is 1.8.6.

Then we can factorise again, as my tests with a fresh install from start folder AND my tests from my personal chapter 22 folder make the same results. The good new in this is that you will be able to reproduce my bugs very easily.

  • When I use the line composer require --dev liip/functional-test-bundle:^1.9, it never works :

λ composer require --dev liip/functional-test-bundle:^1.9

Could not find package liip/functional-test-bundle in a version matching 1.9`

  • With the composer require --dev liip/functional-test-bundle without forcing version, we come back on my original bug, after setting up the php memory to 4096M :

D:\Developpement\Dinopark (master)
λ composer require --dev liip/functional-test-bundle
Using version ^4.2 for liip/functional-test-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1

- symfony/browser-kit v5.1.5 requires php >=7.2.5 -> your PHP version (7.3.19) overridden by "config.platform.php" version (7.1.3) does not satisfy that requirement.
- Installation request for liip/functional-test-bundle ^4.2 -> satisfiable by liip/functional-test-bundle[4.2.0].
- Conclusion: remove symfony/symfony v3.3.10
- Conclusion: don't install symfony/symfony v3.3.10
- liip/functional-test-bundle 4.2.0 requires symfony/browser-kit ^3.4 || ^4.1 || ^5.0 -> satisfiable by symfony/browser-kit[v3.4.0, v3.4.1, v3.4.10, v3.4.11, v3.4.12, v3.4.13, v3.4.14, v3.4.15, v3.4.16, v3.4.17, v3.4.18, v3.4.19, v3.4.2, v3.4.20, v3.4.21, v3.4.22, v3.4.23, v3.4.24, v3.4.25, v3.4.26, v3.4.27, v3.4.28, v3.4.29, v3.4.3, v3.4.30, v3.4.31, v3.4.32, v3.4.33, v3.4.34, v3.4.35, v3.4.36, v3.4.37, v3.4.38, v3.4.39, v3.4.4, v3.4.40, v3.4.41, v3.4.42, v3.4.43, v3.4.44, v3.4.5, v3.4.6, v3.4.7, v3.4.8, v3.4.9, v4.1.0, v4.1.1, v4.1.10, v4.1.11, v4.1.12, v4.1.2, v4.1.3, v4.1.4, v4.1.5, v4.1.6, v4.1.7, v4.1.8, v4.1.9, v4.2.0, v4.2.1, v4.2.10, v4.2.11, v4.2.12, v4.2.2, v4.2.3, v4.2.4, v4.2.5, v4.2.6, v4.2.7, v4.2.8, v4.2.9, v4.3.0, v4.3.1, v4.3.10, v4.3.11, v4.3.2, v4.3.3, v4.3.4, v4.3.5, v4.3.6, v4.3.7, v4.3.8, v4.3.9, v4.4.0, v4.4.1, v4.4.10, v4.4.11, v4.4.12, v4.4.13, v4.4.2, v4.4.3, v4.4.4, v4.4.5, v4.4.6, v4.4.7, v4.4.8, v4.4.9, v5.0.0, v5.0.1, v5.0.10, v5.0.11, v5.0.2, v5.0.3, v5.0.4, v5.0.5, v5.0.6, v5.0.7, v5.0.8, v5.0.9, v5.1.0, v5.1.1, v5.1.2, v5.1.3, v5.1.4, v5.1.5].
- don't install symfony/browser-kit v3.4.0|don't install symfony/symfony v3.3.10
- Installation request for symfony/symfony (locked at v3.3.10, required as 3.3.*) -> satisfiable by symfony/symfony[v3.3.10].

Installation failed, reverting ./composer.json to its original content.

This is a shortened version of the bug, as the real one is very long.

So if I don't fail any important step, we have :

  • A project where the last PHP versions doesn't work,
  • No matter what I try, liip bundle doesn't work.

Let me know if you need screenshots for the error messages, but I think it's now really easy for you to test this out ;)

<blockquote>❤️ I'll pass that feedback to the team. And sorry again for the issue :).</blockquote>

No problem, in fact my message was more about "Keep this course for the future of symfonyCasts because it is so cool" more than "there is a bug in this tutorial" you know :)

I would add also that since symfony 3, PHPUnit and PHPUnit bridge evolved, and the way to test your app changed a bit (for example, I think now it's something like php bin/phpunit ? Or this is the old version...), so a lot of reason to refresh your awesome dinopark !

Cheers !


Hey Julien R.!

Sorry for the slow reply and thanks for the detailed reply and taking so much time to test thing - I really appreciate that :).

Let's unpack some things :)

1) About PHP 7.4 not working

This is a known issue - it's due to some dependencies not being compatible with PHP 7.4 and upgrading them would require major version upgrades. To help with this, we recently launched a feature where we advertise this fact when you download the course code:

<img src="https://i.imgur.com/A1vDSgy.png&quot;&gt;

But perhaps this isn't obvious enough? Or is hard to understand? Perhaps it should exactly say "This tutorial does not work in PHP 7.4 and higher"? Let me know - this is a relatively new feature, and this was our first attempt at sharing this information. And yes, ideally the tutorial would work with the latest version of PHP, and we upgrade dependencies to make this happen whenever that's feasible. But when it's not, we want to make it obvious. The fact that the tutorial doesn't work with PHP 7.4 definitely motivates us to upgrade it ;).

2) About composer require --dev liip/functional-test-bundle:^1.9 not working

Hmm. What if you surround the argument with quotes?

composer require --dev "liip/functional-test-bundle:^1.9"

I'm asking because I just tried this command on the "start" code and it DID work. I'm wondering if your shell is treating "^" as a special character, and so it's looking exactly for a version called 1.9 (when I run the command, it actually installs 1.10.0). Let me know!

No problem, in fact my message was more about "Keep this course for the future of symfonyCasts because it is so cool" more than "there is a bug in this tutorial" you know :)

I really appreciate this! It's something we work on and think about a lot and we're hoping to add some additional testing to our tutorials this year to know when there are php version problems of library install problems.

I would add also that since symfony 3, PHPUnit and PHPUnit bridge evolved, and the way to test your app changed a bit (for example, I think now it's something like php bin/phpunit ? Or this is the old version...), so a lot of reason to refresh your awesome dinopark !



Benoit L. Avatar
Benoit L. Avatar Benoit L. | posted 3 years ago | edited

Update : some how I managed to do the login with :
$form = $crawler->filter('html > body > div > form')->form();
The problem now is I don't know how to log out, the session stays active between two tests.

Hi everybody, I had a hard time making a basic functional test work, I need to login in the first place. I use symfony 4.4, I find the different tutorials on internet confusing, many ways to do thing..., here is my code (symfony CssSelector is installed):
` public function testLoginToApp()


    $client = static::createClient([], [
        'PHP_AUTH_USER' => 'yvon@mymail.com',
        'PHP_AUTH_PW' => 'mypass',

       $crawler = $client->request('GET', '/login');
       $form = $crawler->filter('#loginForm');
       $crawler = $client->followRedirect();

 //   $this->assertEquals(302, $client->getResponse()->getStatusCode());


I just want to login and test if I can access certain routes.
However the nodelist is empty, it cannot find the button# to post data. What did I do wrong?


Hey Benoit L.

The only difference between your first attempt to submit the form and the later one is that you forgot to call ->form() after filtering the response e.g. $crawler->filter('#loginForm')->form();

The problem now is I don't know how to log out, the session stays active between two tests.
Really? I wouldn't expect that behavior but what you can do is just to hit your logout path, that should do the work

by the way, check out this post https://symfony.com/blog/new-in-symfony-5-1-simpler-login-in-tests
for your subsequent tests it would be better to just "simulate" the login and perform the action under test


Benoit L. Avatar

Hi thank you for your tip, unfortunately I am not in symfony 5 and the app is already in production, I wouldn't date making that change. I will visit the logout page prior to do anything else, or empty a cache. I think it would be interesting to put that in tearDown function

Benoit L. Avatar

I think I understood why I couldn't get the text of login page, because with the static::createClient() with the credential , you are already logged in, no need to post credential via submit !

1 Reply

Cool! I'm glad to hear you could find what's going on here. Thanks for sharing it.


I've been trying to install liip's bundle for more than an hour now. I'm giving up this course for tonight but can anyone please provide a version number that should install?
composer/ca-bundle 1.2.7 Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.
doctrine/annotations 1.10.1 Docblock Annotations Parser
doctrine/cache 1.10.0 PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and ...
doctrine/collections 1.6.4 PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.
doctrine/common 2.12.0 PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflec...
doctrine/data-fixtures 1.4.2 Data Fixtures for all Doctrine Object Managers
doctrine/dbal v2.10.1 Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.
doctrine/doctrine-bundle 1.10.3 Symfony DoctrineBundle
doctrine/doctrine-cache-bundle 1.3.5 Symfony Bundle for Doctrine Cache
doctrine/event-manager 1.1.0 The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.
doctrine/inflector 1.3.1 Common String Manipulations with regard to casing and singular/plural rules.
doctrine/instantiator 1.3.0 A small, lightweight utility to instantiate objects in PHP without invoking their constructors
doctrine/lexer 1.2.0 PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.
doctrine/orm v2.7.2 Object-Relational-Mapper for PHP
doctrine/persistence 1.3.7 The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.
doctrine/reflection 1.2.1 The Doctrine Reflection project is a simple library used by the various Doctrine projects which adds some additional functionality on top of...
fig/link-util 1.1.0 Common utility implementations for HTTP links
incenteev/composer-parameter-handler v2.1.4 Composer script handling your ignored parameter file
jdorn/sql-formatter v1.2.17 a PHP SQL highlighting library
monolog/monolog 1.25.3 Sends your logs to files, sockets, inboxes, databases and various web services
myclabs/deep-copy 1.9.5 Create deep copies (clones) of your objects
ocramius/package-versions 1.4.2 Composer plugin that provides efficient querying for installed package versions (no runtime IO)
paragonie/random_compat v9.99.99 PHP 5.x polyfill for random_bytes() and randomint() from PHP 7 phar-io/manifest 1.0.1 Component for reading phar.io manifest information from a PHP Archive (PHAR) phar-io/version 1.0.1 Library for handling version information and constraints phpdocumentor/reflection-common 2.0.0 Common reflection classes used by phpdocumentor to reflect the code structure phpdocumentor/reflection-docblock 5.1.0 With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a Doc... phpdocumentor/type-resolver 1.1.0 A PSR-5 based resolver of Class names, Types and Structural Element Names phpspec/prophecy v1.10.3 Highly opinionated mocking framework for PHP 5.3+ phpunit/php-code-coverage 5.3.2 Library that provides collection, processing, and rendering functionality for PHP code coverage information. phpunit/php-file-iterator 1.4.5 FilterIterator implementation that filters files based on a list of suffixes. phpunit/php-text-template 1.2.1 Simple template engine. phpunit/php-timer 1.0.9 Utility class for timing phpunit/php-token-stream 2.0.2 Wrapper around PHP's tokenizer extension. phpunit/phpunit 6.3.0 The PHP Unit Testing framework. phpunit/phpunit-mock-objects 4.0.4 Mock Object library for PHPUnit psr/cache 1.0.1 Common interface for caching libraries psr/container 1.0.0 Common Container Interface (PHP FIG PSR-11) psr/link 1.0.0 Common interfaces for HTTP links psr/log 1.1.3 Common interface for logging libraries psr/simple-cache 1.0.1 Common interfaces for simple caching sebastian/code-unit-reverse-lookup 1.0.1 Looks up which function or method a line of code belongs to sebastian/comparator 2.1.3 Provides the functionality to compare PHP values for equality sebastian/diff 2.0.1 Diff implementation sebastian/environment 3.1.0 Provides functionality to handle HHVM/PHP environments sebastian/exporter 3.1.2 Provides the functionality to export PHP variables for visualization sebastian/global-state 2.0.0 Snapshotting of global state sebastian/object-enumerator 3.0.3 Traverses array structures and object graphs to enumerate all referenced objects sebastian/object-reflector 1.1.1 Allows reflection of object attributes, including inherited and non-public ones sebastian/recursion-context 3.0.0 Provides functionality to recursively process PHP variables sebastian/resource-operations 1.0.0 Provides a list of PHP built-in functions that operate on resources sebastian/version 2.0.1 Library that helps with managing the version number of Git-hosted PHP projects sensio/distribution-bundle v5.0.25 Base bundle for Symfony Distributions sensio/framework-extra-bundle v3.0.29 This bundle provides a way to configure your controllers with annotations sensio/generator-bundle v3.1.7 This bundle generates code for you sensiolabs/security-checker v5.0.3 A security checker for your composer.lock swiftmailer/swiftmailer v5.4.12 Swiftmailer, free feature-rich PHP mailer symfony/monolog-bundle v3.2.0 Symfony MonologBundle symfony/polyfill-apcu v1.15.0 Symfony polyfill backporting apcu* functions to lower PHP versions
symfony/polyfill-ctype v1.15.0 Symfony polyfill for ctype functions
symfony/polyfill-intl-icu v1.15.0 Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring v1.15.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php56 v1.15.0 Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions
symfony/polyfill-php70 v1.15.0 Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-util v1.15.0 Symfony utilities for portability of PHP codes
symfony/swiftmailer-bundle v2.6.7 Symfony SwiftmailerBundle
symfony/symfony v3.3.18 The Symfony PHP framework
theseer/tokenizer 1.1.3 A small library for converting tokenized PHP source code into XML and potentially other formats
twig/twig v2.12.5 Twig, the flexible, fast, and secure template language for PHP
webmozart/assert 1.8.0 Assertions to validate method input/output with nice error messages.



Wow I never look to the content below the videos, just saw the *tip*. Answer is: liip/functional-test-bundle:^1.9


Hey julien_bonnier

Yeah sometimes it can be useful :))))

We are glad that you solved your issue! Feel free to ask any questions!


Lijana Z. Avatar
Lijana Z. Avatar Lijana Z. | posted 5 years ago

if when clicks buttons it is called functional test, then what is end to end test?


Hey Lijana Z.

Good question, an end-to-end test is when you test the entire flow of a feature in your system, in other words, you test that all your components communicates as expected, in this kind of tests you don't mock anything, if you have to store something in the DB, you configure a test DB, if you have to hit an external resource like an API, first you have to find if they offer a sandbox endpoint, if not, then you would have to create a test account so you can use those credentials in your tests


Lijana Z. Avatar

Hi, so in functgional test we still mock some classes?


Usually you don't, but if you don't care about *that* service (maybe it's just a dependency that you are not exercicing in that test), then you can mock it out.

Cat in space

"Houston: no signs of life"
Start the conversation!

While the fundamentals of PHPUnit haven't changed, this tutorial *is* built on an older version of Symfony and PHPUnit.

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": "^7.0, <7.4",
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "doctrine/doctrine-bundle": "^1.6", // 1.10.3
        "doctrine/orm": "^2.5", // v2.7.2
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "sensio/distribution-bundle": "^5.0.19", // v5.0.21
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.28
        "symfony/monolog-bundle": "^3.1.0", // v3.1.2
        "symfony/polyfill-apcu": "^1.0", // v1.6.0
        "symfony/swiftmailer-bundle": "^2.3.10", // v2.6.7
        "symfony/symfony": "3.3.*", // v3.3.13
        "twig/twig": "^1.0||^2.0" // v2.4.4
    "require-dev": {
        "doctrine/data-fixtures": "^1.3", // 1.3.3
        "doctrine/doctrine-fixtures-bundle": "^2.3", // v2.4.1
        "liip/functional-test-bundle": "^1.8", // 1.8.0
        "phpunit/phpunit": "^6.3", // 6.5.2
        "sensio/generator-bundle": "^3.0", // v3.1.6
        "symfony/phpunit-bridge": "^3.0" // v3.4.30