My team and I started on Drupal some months ago. As we began creating our own modules, I also wanted to test them, but was very annoyed by the Performance of the tests - or better: of the Performance of core/tests/bootstrap.php:
- It takes about 35 seconds after entering the phpunit-command until the tests have passed.
- The Unit-Tests themselves in my modules take 1-2 Seconds to pass.
- All the other time is spent in building up phpunit, especially in
core/tests/bootstrap.php
#drupal_phpunit_populate_class_loader()
The reason: Although I only want to test my module, bootstrap.php scans every path in all the modules, profiles and themes in core and contrib for populating $GLOBALS['namespaces']
. IMHO, 30seconds of bootstraping for any tests prohibits fast and often testing and therefor makes test-driven development impossible.
I found that I can significantly improve the performance by calling phpunit with the UnitTest-Folder as argument (phpunit modules/custom/modulename/tests/src/Unit
) and changing $paths
in drupal_phpunit_contrib_extension_directory_roots()
:
$paths = [
// $root . '/core/modules',
// $root . '/core/profiles',
// $root . '/core/themes',
// $root . '/modules',
// $root . '/profiles',
// $root . '/themes',
$root . '/modules/custom',
$root . '/themes/custom'
With this change, bootstraping the tests takes about 1-2 seconds, which would be accetable for me. But it works only for UnitTest, Kernel- and Browser-Tests run no more.
So my questions:
- Is bootstraping of around 30sec for running of phpunit under drupal considered as 'normal' or is this a sign of something broken in my installation?
- Is there any proposed way to reduce bootstraping time when doing only UnitTests?
- I suppose I could create a second phpunit.xml, referring to an alternative core/tests/bootstrap.php with a $paths, which is reduced to our custom modules. And then, I would call phpunit with
-c
-option for the alternate phpunit.xml and the Unittest-Folder as argument. Is this a good idea or a sure way to shoot myself in the foot?
======
Update: Thanks to the Feedback from Kevin, I once more investigated why core/tests/bootstrap.php took so long to populate the classloader: The culprit is not bootstrap.php/drupal, but vagrant/virtualbox:
If I run the unit-tests from outside vagrant, they run in 1-2 seconds, as it seems normal to me (and is along what Kevin said)
If I run them inside the vagrant, the they take >30seconds.
The difference is in bootstrap.php, when drupal_phpunit_find_extension_directories()
iterates over all Module-, Profile- and Theme-Directories in core, contrib and sites. Those directories are mounted via the Sync Folder-Feature by Vagrant, where there is a known performance-issue with Virtualbox.
Therefore, I renounce from hacking core :)