A quick and simple way to make your functional tests independent with Symfony and mysql

Having independent functional tests is a good practice recommended by many developers. It allows you save a great deal of time; and it is well known, time is money!


If your tests are not independent, it means that the execution of one test can impact the result of the following tests. Dependent tests can in fact fail randomly depending on the order of execution.

I started working on a small project with a small amount of tests and I did not notice the problem at first. But as we added features, the number of tests increased significantly. And they started failing randomly. The bigger the project, the more difficult it is to understand why tests fail. We lost hours trying to find out the root cause of the failures. Indeed, the cause was not in the failing tests itself, but the failure was due to the execution of one test before. It thus took us a lot of time and energy to maintain our tests on a daily basis.

Therefore, we decided to solve the problem and make our tests independent in a quick and simple way : reset the database between each test to make them start with a clean set of data. We set one constraint: to not impact the performances !

Let’s practice

As I mentioned before, in order to make our tests independent we chose to reset the database before each test using a dump
file. Here are the two main steps of the process:

    • Create an sql dump from your test database: To run your functional tests, you need to create a database. Right after this
      set up, create a dump of it :
mysqldump -u $USER -h $HOST -p $PASSWORD $BDD_NAME > dump_db_test.sql
    • Reset your database before each test: Once the dump is created, we will use it to reset the database. You can create
      an AbstractBaseTestCase.php extending the \PHPUnit_Framework_TestCase. Every functional test file should extend this file. In this file, create a setUp() method which will be run before each of your tests. This method will execute the command to reset the database with the dump file created before :
abstract class AbstractBaseTestCase extends \PHPUnit_Framework_TestCase
        public function setUp()
            $importCommand =
        mysql -h mysqlHost -u mysqlUserName -p mysqlPassword mysqlDatabaseName < mysqlImportFilename;


Before executing one functional test, this method is executed and it cleans the database. The following test then uses a new set of data and the previous modifications of the database do not impact the running test.

Going further

  • As you may have noticed, each time you’re using a plaintext password in the command line, a warning is printed in the console.
    To avoid this you can set up the password as an environment variable.

    Export MYSQL_PWD=’mysqlPassword’
  • As a quick solution, we decided to use the same database for each test. It is possible to improve this model and use fixtures
    to load before each test only the ones needed to run the tests.

You liked this article? You'd probably be a good match for our ever-growing tech team at Theodo.

Join Us

  • Amine Ben Hariz

    You can use sqlite3 for unit-testing : It’s easier to setup (no mysql server), faster (it could be RAM based), and since it’s a file, no dump is needed for resetting, just copying the file!

  • Alex

    And no username / password :)

  • David Maicher

    I would recommend to check out this bundle if you are using Doctrine as well:


    Its a lot faster and very simple to setup.

  • David Maicher

    With the big disadvantage that you are using a different DB for tests than on production. This means you cannot really trust your tests 😉

  • SQLite can be used in unit tests where it can avoid mocking the persistence layer, but I agree it should not be used in functional tests. Functional tests should run on the same DB.