Skip to content

Instantly share code, notes, and snippets.

@davidjguru
Last active April 11, 2024 08:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save davidjguru/dd645fedef51008fe6b7f8753880b09f to your computer and use it in GitHub Desktop.
Save davidjguru/dd645fedef51008fe6b7f8753880b09f to your computer and use it in GitHub Desktop.
Drupal 8 || 9 - Configure your PHPUnit environment for functional testing

Drupal 8 || 9 - Configure your environment for functional testing with PHPUnit

If you need an extended and specific version of this topic, read this article:
*Functional testing for Browser in Drupal 8-9 using PHPUnit

Author

Acknowledgments

This gist was composed from my current position as Senior Drupal Developer at Digitalist Sweden, one of the biggest companies oriented to Open Source in Europe and specifically focused in Drupal.

1- Know your versions

The first step is to know what versions are you using in your Drupal installation. Drupal changes PHPUnit required versions in Drupal 8, Drupal 9 and the PHP installed version.
For instance, for Drupal 8 deploys you can use PHPUnit 7.x, (7.5.20 in my last test). For Drupal 9 you can use PHPUnit 8.x but if your PHP version is > 7.3 you can use PHPUnit 9.x. So first, get info about Drupal and PHP.

See the Issue: Update to PHPUnit 9

$ composer show drupal/core |grep versions
versions : * 9.2.7
$ php -v

PHP 7.4.20 (cli) (built: Jun  4 2021 23:17:27) ( NTS )

$ composer show drupal/core |grep versions
versions : * 8.9.19

2- Resolve dependencies

For my Drupal 9 deploy, I can request something like:

$ composer require --dev phpunit/phpunit --with-all-dependencies
$ composer require --dev symfony/phpunit-bridge
$ composer require --dev behat/mink-goutte-driver
$ composer require --dev behat/mink-selenium2-driver
$ composer require --dev phpspec/prophecy-phpunit:^2

Or:

$ composer require --dev phpunit/phpunit symfony/phpunit-bridge \  
                         behat/mink-goutte-driver behat/mink-selenium2-driver \
                         phpspec/prophecy-phpunit --with-all-dependencies

Getting:

[...]
Using version ^9.5 for phpunit/phpunit
Using version ^5.3 for symfony/phpunit-bridge
Using version ^1.3 for behat/mink-goutte-driver
Using version ^1.5 for behat/mink-selenium2-driver
Using version ^2.0 for phpspec/prophecy-phpunit

But for Drupal 8 I'm installing:

$ ddev composer require phpunit/phpunit:^7 --with-dependencies
$ composer require phpunit/phpunit:^7
$ composer require symfony/phpunit-bridge:^3.4.3
$ composer require behat/behat:^3.4
$ composer require behat/mink:^1.8
$ composer require behat/mink-goutte-driver:^1.2
$ composer require behat/mink-selenium2-driver:^1.5.0

3- Copy and rename the phpunit.xml file

Locate the file at /project/web/core/phpunit.xml.dist. It’s necessary to make a copy of the file and rename it as phpunit.xml

$ cp /project/web/core/phpunit.xml.dist phpunit.xml

4- Set basic values for your phpunit.xml file

Then, edit the phpunit.xml file and set new values in <php> section of the file.

<php>
  [...]
  <env name="SIMPLETEST_BASE_URL" value="http://localhost"/>
  <env name="SIMPLETEST_DB" value="mysql://username:password@localhost/databasename"/>
  <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/html/web/sites/default/simpletest/browser_output/"/>
  <env name="BROWSERTEST_OUTPUT_BASE_URL" value="http://localdeployname.ddev.site/"/>
  [...]
</php>

5- Connect to the container and check some test in contrib modules

$ ddev ssh
davidjguru@container-web:/var/www/html$ cd web/
davidjguru@container-web:/var/www/html/web$ ../vendor/bin/phpunit -c core modules/contrib/admin_toolbar

Returning:

[...]
  PHPUnit 9.5.10 by Sebastian Bergmann and contributors.
  Testing /var/www/html/web/modules/contrib/admin_toolbar
  .SSS....                                                            8 / 8 (100%)
  Time: 01:01.877, Memory: 6.00 MB
 
  OK, but incomplete, skipped, or risky tests!
  Tests: 8, Assertions: 110, Skipped: 3.
[...]

So, everything is going well! ready to run your own test! Happy Hacking!

6- Go fast (extra)

I have some basic scripts with all of these steps, ready-to-go creating new Drupal 9 local deploys using DDEV, preparing the Drupal 9 deploy for PHPUnit (and launching an initial testing in a contrib existing module) and finally stopping containers, disabling the DDEV deploy and deleting the project folder.

See the next bash script, download, add in your ~/.bashrc file and use the functions. Example:

$ d9ddev # Create a new D9 deploy with a random naming.
newdeploy$ d9phpunit # Within the D9 deploy prepares PHPUnit and launch initial testing.
newdeploy$ ddevdestroy #Stop the DDEV deploy, disabling the containers and deleting content.
$ # Returns to the previous folder. 

Or you can use:

$ d9ddev && d9phpunit
$ d8ddev && d8phpunit

This Require using DDEV for local deploys, you can read more about this tool here:

## Creating Drupal projects by using DDEV.
d9ddev () {
if [ -z "$1" ]
then
check=$(shuf -n1 /usr/share/dict/words)
shortened=${check::-2}
varkeyname=${shortened,,}
else
varkeyname=$1
fi
mkdir $varkeyname && cd $varkeyname
ddev config --project-type=drupal9 --docroot=web --create-docroot
yes | ddev composer create "drupal/recommended-project:^9"
ddev composer require drush/drush drupal/admin_toolbar drupal/devel
ddev exec drush si --site-name=$varkeyname --account-name=admin --account-pass=admin -y
ddev drush en -y admin_toolbar admin_toolbar_tools admin_toolbar_search admin_toolbar_links_access_filter devel
ddev drush cr
ddev start && ddev launch
}
## Prepares a Drupal 9 installation for testing with PHPUnit executing from project folder.
d9phpunit () {
varkeyname=basename $(pwd)
string_url="<env name='BROWSERTEST_OUTPUT_BASE_URL' value='http://${varkeyname}.ddev.site/'/>"
ddev composer require --dev phpunit/phpunit symfony/phpunit-bridge \
behat/mink-goutte-driver behat/mink-selenium2-driver \
phpspec/prophecy-phpunit --with-all-dependencies
cd web/core
cp phpunit.xml.dist phpunit.xml
sed -i 's+<env name="SIMPLETEST_BASE_URL" value=""/>+<env name="SIMPLETEST_BASE_URL" value="http://localhost"/>+g' phpunit.xml
sed -i 's+<env name="SIMPLETEST_DB" value=""/>+<env name="SIMPLETEST_DB" value="mysql://db:db@db/db"/>+g' phpunit.xml
sed -i 's+<env name="BROWSERTEST_OUTPUT_DIRECTORY" value=""/>+<env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/html/web/sites/default/simpletest/browser_output/"/>+g' phpunit.xml
sed -i 's+<env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/>+'"$string_url"'+g' phpunit.xml
cd ../..
ddev exec ./vendor/bin/phpunit -c web/core /var/www/html/web/modules/contrib/admin_toolbar
}
## Same but for Drupal 8.
d8phpunit () {
varkeyname=basename $(pwd)
string_url="<env name='BROWSERTEST_OUTPUT_BASE_URL' value='http://${varkeyname}.ddev.site/'/>"
ddev composer require --dev phpunit/phpunit:^7 symfony/phpunit-bridge:^3.4.3 \
behat/mink-goutte-driver:^1.2 behat/behat:^3.4 behat/mink:^1.8 \
behat/mink-selenium2-driver:^1.5.0 --with-all-dependencies
cd web/core
cp phpunit.xml.dist phpunit.xml
sed -i 's+<env name="SIMPLETEST_BASE_URL" value=""/>+<env name="SIMPLETEST_BASE_URL" value="http://localhost"/>+g' phpunit.xml
sed -i 's+<env name="SIMPLETEST_DB" value=""/>+<env name="SIMPLETEST_DB" value="mysql://db:db@db/db"/>+g' phpunit.xml
sed -i 's+<env name="BROWSERTEST_OUTPUT_DIRECTORY" value=""/>+<env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/html/web/sites/default/simpletest/browser_output/"/>+g' phpunit.xml
sed -i 's+<env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/>+'"$string_url"'+g' phpunit.xml
cd ../..
ddev exec ./vendor/bin/phpunit -c web/core /var/www/html/web/modules/contrib/admin_toolbar
}
## Destroy a DDEV local deploy by name using in project folder.
ddevdestroy () {
varkeyname=basename $(pwd)
ddev stop
yes |ddev delete -O
cd ..
rm -rf $varkeyname
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment