3

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:

  1. 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?
  2. Is there any proposed way to reduce bootstraping time when doing only UnitTests?
  3. 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 :)

1
  • 1
    This sounds wrong. Unit tests execute very quickly as its only running raw code, there is no full Drupal bootstrap like Kernel or Functional tests. I can run 100 unit tests on my projects in a few seconds or less. phpunit can take arguments of which types of tests to run. Make sure your <testsuites> directive in phpunit.xml is set only to the path(s) of your custom module folder.
    – Kevin
    Commented Jun 16, 2022 at 13:18

1 Answer 1

3

Kernel and Functional tests are expected to take longer because of a full Drupal bootstrap and site scaffolding per run to test in a clean environment. Unit tests are running raw code and should execute very quickly. I can run a few hundred of them in a matter of seconds.

Ensure your phpunit.xml file is set up correctly. For example, scanning for tests only in the custom module directory:

<testsuites>
    <testsuite name="unit">
      <directory>web/modules/custom/*/tests/src/Unit</directory>
    </testsuite>
    <testsuite name="kernel">
      <directory>web/modules/custom/*/tests/src/Kernel</directory>
    </testsuite>
    <testsuite name="functional">
      <directory>web/modules/custom/*/tests/src/Functional</directory>
    </testsuite>
  </testsuites>

Or running a specific kind of test:

phpunit --testsuite unit

Other than that something is wrong with your setup. It should never take 30 seconds to kickstart a unit test. Make sure you are not running with xdebug enabled and listening, etc.

(also, dont hack core!)

3
  • Thank you for your feedback. phpunit.xml was ok, as was my usage of the phpunit-command. The problem really could be isolated to core/tests/bootstrap.php, when it populates the classloader. But thanks to your feedback, I investigated this step again and found that the problem lies within vagrant and virtualbox, and not within bootstrap.php itself.
    – mullzk
    Commented Jun 16, 2022 at 14:47
  • Just as an aside, altough now only theoretical: If I use my own phpunit.xml (copied from core to drupal-root and then altered), and refer to another bootstrap.php (copied from core/tests, and then altered), would this still be considered hacking core? The original files would be left unchanged.
    – mullzk
    Commented Jun 16, 2022 at 14:51
  • I don't know what the use case is for that.
    – Kevin
    Commented Jun 16, 2022 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.