Testing Symfony 5 applications - Use special test classes

Article Index

Use special test classes

Usually unit tests are derived from PHPUnit\Framework\TestCase, controller tests from Symfony\Bundle\FrameworkBundle\Test\WebTestCase. But to add some functionality, I created these two classes of my own. Both are derived from Liip\FunctionalTestBundle\Test\WebTestCase. I have added several functions to simplify testing:

Method TestCase WebTestCase Description
checkContainerRegistration x   Check if a service class is registered correctly in the service container.
checkLinkOnDashboardPage   x Check if a certain link is found on the the general or on the administration dashboard page.
clearAllLogFiles x x Clear the logfile entry database table. This is used when the test has to check if the correct log entries are generated. This is easier when clearing the log table before the new log entries are generated.
getAllLogs x x Read all logfile entries from the database.
getEntityManager x x Return the current entity manager.
getFixtureReference x x Return a database entity by calling its string name from the fixture reference string.
getMyClient   x Return the client, in the passed user is logged in. When calling this with a different user, this new user is logged in.
getTranslator x x Return the current translator service.
loadAllFixtures x x Load all fixtures for the passed group. This is the same as calling ./bin/console doctrine:fixtures:load --group=<the passed group>. Passing no group the method will load the default group fixtures. Passing a non-existing group will not load any fixtures, i.e. removing all data from the database.
onNotSuccessfulTest x x This is called when a test fails. It writes the output of the test to a file under var/tests. When the test is a web test case, the complete html output is written to this file, so it can be opened with a web browser to see what the page looked like at the time of the failure.
setGuiLanguage   x Change to current locale, so the next page request is in the defined language.
setLoggedInUserForLogging x x Define the user under which all logs are generated during the next test.

You can have a look at the source code of this here: TestCase, WebTestCase and TestCaseTrait (for common functions used by both of them)

By defining the method onNotSuccessfulTest, I can debug what went wrong when a test fails. On failure, it creates an html file under var/test, which is called like the test class and the test case, e.g. App_Tests_Controller_Member_MemberContactDataControllerTest___testShowEdit.html. For unit tests (using TestCase), this file only contains the stack dump for the test. For integration tests, which use WebTestCase, this dumps the last html seen by the test before it failed. With that, you can open this file in the browser and see the page like the test saw it before it failed. This makes it a lot easier analysing the cause of the failure: is the test or the app broken?