Problem/Motivation
I've followed the steps in this tutorial: https://mglaman.dev/blog/running-drupals-phpunit-test-suites-ddev but I'm finding my test always fails as the database connection used when drupalGet() is called is missing the `test{TEST_ID}` prefix and so the get is run against the main database tables and not the test ones.
First off this is the require-dev section of my `composer.json` file:
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"drupal/core-dev": "8.8.8"
},
I've copied the `core/phpunit.xml.dist` file to my docroot and have renamed to `phpunit.xml`
<?xml version="1.0" encoding="UTF-8"?>
<!-- TODO set checkForUnintentionallyCoveredCode="true" once https://www.drupal.org/node/2626832 is resolved. -->
<!-- PHPUnit expects functional tests to be run with either a privileged user
or your current system user. See core/tests/README.md and
https://www.drupal.org/node/2116263 for details.
-->
<phpunit bootstrap="web/core/tests/bootstrap.php" colors="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutChangesToGlobalState="true"
printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter">
<php>
<!-- Set error reporting to E_ALL. -->
<ini name="error_reporting" value="32767"/>
<!-- Do not limit the amount of memory tests take to run. -->
<ini name="memory_limit" value="-1"/>
<!-- Example SIMPLETEST_BASE_URL value: http://localhost -->
<env name="SIMPLETEST_BASE_URL" value="http://localhost"/>
<!-- Example SIMPLETEST_DB value: mysql://username:password@localhost/databasename#table_prefix -->
<env name="SIMPLETEST_DB" value="mysql://db:db@db/db"/>
<!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output -->
<env name="BROWSERTEST_OUTPUT_DIRECTORY" value="sites/simpletest/browser_output"/>
<!-- To have browsertest output use an alternative base URL. For example if
SIMPLETEST_BASE_URL is an internal DDEV URL, you can set this to the
external DDev URL so you can follow the links directly.
-->
<env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/>
<!-- To disable deprecation testing completely uncomment the next line. -->
<!-- <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/> -->
<!-- Example for changing the driver class for mink tests MINK_DRIVER_CLASS value: 'Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver' -->
<env name="MINK_DRIVER_CLASS" value=''/>
<!-- Example for changing the driver args to mink tests MINK_DRIVER_ARGS value: '["http://127.0.0.1:8510"]' -->
<env name="MINK_DRIVER_ARGS" value=''/>
<!-- Example for changing the driver args to phantomjs tests MINK_DRIVER_ARGS_PHANTOMJS value: '["http://127.0.0.1:8510"]' -->
<env name="MINK_DRIVER_ARGS_PHANTOMJS" value=''/>
<!-- Example for changing the driver args to webdriver tests MINK_DRIVER_ARGS_WEBDRIVER value: '["chrome", { "chromeOptions": { "w3c": false } }, "http://localhost:4444/wd/hub"]' For using the Firefox browser, replace "chrome" with "firefox" -->
<env name="MINK_DRIVER_ARGS_WEBDRIVER" value=''/>
</php>
<testsuites>
<testsuite name="unit">
<file>./tests/TestSuites/UnitTestSuite.php</file>
</testsuite>
<testsuite name="kernel">
<file>./tests/TestSuites/KernelTestSuite.php</file>
</testsuite>
<testsuite name="functional">
<file>./tests/TestSuites/FunctionalTestSuite.php</file>
</testsuite>
<testsuite name="functional-javascript">
<file>./tests/TestSuites/FunctionalJavascriptTestSuite.php</file>
</testsuite>
<testsuite name="build">
<file>./tests/TestSuites/BuildTestSuite.php</file>
</testsuite>
</testsuites>
<!-- Filter for coverage reports. -->
<filter>
<whitelist>
<directory>./includes</directory>
<directory>./lib</directory>
<!-- Extensions can have their own test directories, so exclude those. -->
<directory>./modules</directory>
<exclude>
<directory>./modules/*/src/Tests</directory>
<directory>./modules/*/tests</directory>
</exclude>
<directory>../modules</directory>
<exclude>
<directory>../modules/*/src/Tests</directory>
<directory>../modules/*/tests</directory>
<directory>../modules/*/*/src/Tests</directory>
<directory>../modules/*/*/tests</directory>
</exclude>
<directory>../sites</directory>
</whitelist>
</filter>
</phpunit>
And I'm running the below test by running:
`../vendor/bin/phpunit -v -c ../phpunit.xml path-to-module`
namespace Drupal\Tests\custom_module\Functional;
use Drupal\node\Entity\Node;
use Drupal\Tests\BrowserTestBase;
/**
* Test the sidebar displays what we expect
*
* @group custom
*/
class RelatedPagesTest extends BrowserTestBase
{
/**
* The modules to load to run the test.
*
* @var array
*/
public static $modules = [
'field',
'node',
'taxonomy',
'custom_module',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
}
public function testRelatedPagesDoesntShowWhenNoContent()
{
$news = $this->container->get('entity_type.manager')->getStorage('node')
->create([
'type' => 'news',
'title' => 'News article without sidebar',
]);
$news->save();
$this->drupalGet('node/' . $news->id());
$this->assertSession()->statusCodeEquals(200);
// Assert sidebar is missing completely
$this->assertText('News article without sidebar');
$this->assertNoText('Show me more');
}
}
With a TON of debug I can see the following is happening:
- The database connection is taken from `phpunit.xml` and sets that as the db connection
- The test{TEST_ID} table prefix is added to the database configuration
- The simpletest/{TEST_ID} folder is created and this copies the database settings from the default/testing.settings.php *The prefix is missing here*
- The test runs and the node is added to the database. Querying the NIDs within the test gives me one nid of 1
- THIS IS THE STEP THAT GOES WRONG
- The test then calls `$this->drupalGet()` for node/1
- The db connection used doesn't have the table prefix so loads the site node/1 (the homepage)
- The test fails
I've been debugging and I can't figure out why the table prefix gets dropped out of the database connection. Any help is much appreciated!
Cheers
Tom