Database-Reload in Symfony-Tests
Everytime i write unit or functional tests in symfony, i have following problem:
Sometimes my tests do not run deterministically because previous ran tests created data, which intefere with following tests. For example (a simple, not really smart one) think of a system which knows one (and only one) user. For my DAL i would test a method like “createUser” or something. Later on i would create a functional test for a registration form. Now the correctness of the tests depend on the sequence, i run the tests. But this should not be this way! Every time i run a test, i have to know the data before i run a part of my software and i have to know how my software manipulates the data (speaking of the date after running my software). The only way i knew to ensure this state, was to run build-all-reload (as in Symfony 1.2 with Doctrine as ORM) to get a fresh database with the predefined fixtures.
Any software you develop will enlarge, and so the tests will, too. After a time you will get to the point, where you can not run a build-all-reload after each test for some reasons. So how about clearing the database before a test runs like the following?
1 2 3 4 5 6 | $browser = new ndTestFunctionalDoctrine(new sfBrowser()); $browser-> reloadData()-> info('1 - Make a test on a clean database with defined fixtures only') ; |
This is what ndTestFunctionalDoctrine offers to test-writing symfony-developers. The only thing you have to handle is: Run reloadData() in your code each time you run a test, which does not depend on the test direct before the current.
Like for functional tests i have a small helper, which can be put to the end of test/bootstrap/unit.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | new sfDatabaseManager($configuration); // helper function reloadData() { // try to drop the database (an exception is thrown, // when the database does not exist) try { Doctrine::dropDatabases(); } catch (Exception $e){ } // create database Doctrine::createDatabases(); // create tables Doctrine::createTablesFromModels(sfConfig::get('sf_lib_dir') . '/model'); // load fixtures Doctrine::loadData(sfConfig::get('sf_data_dir') . '/fixtures'); } |
Analog to this, a version for propel could be build if doctrine is not the ORM of your choice.