The following code will:
- Create a subdirectory
tests_phpunit - Install this package using Composer into
tests_phpunit - Copy
phpunit.dist.xmlfrom Drupal core intotests_phpunit, replacing some values. - Create a test runner at
bin/run_phpunit_tests.sh
curl -sSL https://raw.githubusercontent.com/aklump/drupal-phpunit-integration/main/bin/install.sh | bash -s --export VERSION=^9;curl -sSL https://raw.githubusercontent.com/aklump/drupal-phpunit-integration/main/bin/install.sh | bash -s --- Open
tests_phpunit/phpunit.xml - Replace
testsuites testsuite[name="integration"] directorywith a real path. - Replace
source include directorywith a real path.
chmod u+x bin/run_phpunit_tests.sh- Run tests with
bin/run_phpunit_tests.sh --flush(use--flushjust this first time, or when you need to rebuild the autoloading for dev).
The first time the tests are run, a cache is built that speeds up subsequent
runs. To flush these caches, add the --flush parameter,
e.g. bin/run_phpunit_tests.sh --flush.
Have a look in the following directories:
- tests_phpunit/vendor/aklump/drupal-phpunit-integration/src/Framework/MockObject
- The directory tests_phpunit/src/ is namespaced to
AKlump\Drupal\PHPUnit\Integration - Place shared traits and other test support in src/ using said namespace.
web/modules/custom
└── alpha
├── bin
│ └── run_unit_tests.sh
├── src
│ └── Foo.php
└── tests
├── Integration
│ └── FooTest.php
└── Unit
├── FooTest.php
└── phpunit.xml
Given the above module file structure, you can see two directories in tests. tests/Unit/FooTest.php can be run using alpha/bin/run_unit_tests.sh and has no Drupal dependencies. Therefore it's straight-up PHPUnit stuff. On the other hand, tests/Integration/FooTest.php cannot be run in the same manner as it has Drupal class dependencies, hence it "integrates" with Drupal. For that you must use tests_phpunit/bin/run_phpunit_tests.sh.
Use namespace Drupal\Tests\alpha\Unit; for unit test classes.
Unit tests are only mentioned here to distinguish the difference. This package concerns itself with Integration tests, with one caveat: it is convenient to add the Unit directory to tests_phpunit/phpunit.xml so that Unit tests are run at the same time as the Integration tests. This is a good idea and encouraged. In our example, it will look like this.
<testsuites>
<testsuite name="unit">
<directory>../web/modules/custom/alpha/tests/Unit/</directory>
</testsuite>
<testsuite name="integration">
<directory>../web/modules/custom/alpha/tests/Integration/</directory>
</testsuite>
</testsuites>Before continuing please read the section Difference Between Integration Tests and Unit Tests so you create the tests appropriately.
Create your first integration test class:
web/modules/custom
└── alpha
└── tests
└── Integration
└── FooTest.php
FooTest.php
namespace Drupal\Tests\alpha\Integration;
class FooTest extends \PHPUnit\Framework\TestCase {Ensure your module's web/modules/custom/composer.json has the proper autoloading configuration:
{
"autoload": {
"psr-4": {
"Drupal\\alpha\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Drupal\\Tests\\alpha\\": "./tests/"
}
}
}It's up to you, but it seems like a good idea to source code commit this file as it will provide more stability to your app for tests passing if you have to reinstall dependencies.
To get the newest version of aklump/drupal-phpunit-integration:
cd tests_phpunit
composer updateThis will only update the vendor/ directory so your changes and files in tests_phpunit are not affected.
You may want to diff run_phpunit_tests.sh and phpunit.xml from time to time and cherry pick as necessary, however, CHANGELOG.md should make note of any changes to these files.
cd tests_phpunit
diff vendor/aklump/drupal-phpunit-integration/init/run_phpunit_tests.sh ../bin/run_phpunit_tests.sh
diff vendor/aklump/drupal-phpunit-integration/init/phpunit.xml.dist phpunit.xml