Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .docker/Dockerfile.test
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ FROM govcms/test:${GOVCMS_IMAGE_VERSION}

ENV WEBROOT=web

COPY --from=cli /app /app
COPY --from=cli /app/web /app/web
COPY tests /app/tests/
16 changes: 8 additions & 8 deletions tests/behat/behat.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
default:
autoload: [ %paths.base%/bootstrap ]
autoload: [ '%paths.base%/bootstrap' ]
gherkin:
filters:
# Allow skipping tests by tagging them with "@skipped"
tags: "~@skipped"
suites:
default:
paths: [ %paths.base%/features ]
paths: [ '%paths.base%/features' ]
contexts:
- FeatureContext
- Drupal\DrupalExtension\Context\DrupalContext
- Drupal\DrupalExtension\Context\MinkContext
- Drupal\DrupalExtension\Context\MarkupContext
- Drupal\DrupalExtension\Context\MessageContext
- IntegratedExperts\BehatScreenshotExtension\Context\ScreenshotContext
- DrevOps\BehatScreenshotExtension\Context\ScreenshotContext

extensions:
Behat\MinkExtension:
goutte: ~
browserkit_http: ~
base_url: http://nginx:8080
files_path: %paths.base%/fixtures
files_path: '%paths.base%/files'
browser_name: chrome
selenium2:
wd_host: "http://chrome:4444/wd/hub"
Expand All @@ -40,9 +40,9 @@ default:
success_message_selector: '.messages.status'
warning_message_selector: '.messages.warning'
# Allows to capture HTML and JPG screenshots (based on the driver used).
IntegratedExperts\BehatScreenshotExtension:
dir: %paths.base%/screenshots
fail: true
DrevOps\BehatScreenshotExtension:
dir: '%paths.base%/screenshots'
on_failed: true
purge: false
p0:
gherkin:
Expand Down
87 changes: 23 additions & 64 deletions tests/phpunit/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@

/**
* @file
* Autoloader for Drupal PHPUnit testing.
* Autoloader for GovCMS PHPUnit testing.
*
* @see phpunit.xml.dist
* Based on Drupal core's tests/bootstrap.php, adapted for GovCMS test layout.
*
* @see phpunit.xml
*/

use Drupal\Component\Assertion\Handle;
use PHPUnit\Runner\Version;
declare(strict_types=1);

/**
* Finds all valid extension directories recursively within a given directory.
*
* @param string $scan_directory
* The directory that should be recursively scanned.
*
* @return array
* An associative array of extension directories found within the scanned
* directory, keyed by extension name.
*/
function drupal_phpunit_find_extension_directories($scan_directory)
{
function drupal_phpunit_find_extension_directories($scan_directory) {
$extensions = [];
$dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($scan_directory, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
foreach ($dirs as $dir) {
if (strpos($dir->getPathname(), '.info.yml') !== FALSE) {
if (str_contains($dir->getPathname(), '.info.yml')) {
// Cut off ".info.yml" from the filename for use as the extension name. We
// use getRealPath() so that we can scan extensions represented by
// directory aliases.
Expand All @@ -44,14 +45,14 @@ function drupal_phpunit_find_extension_directories($scan_directory)
* @return array
* An array of directories under which contributed extensions may exist.
*/
function drupal_phpunit_contrib_extension_directory_roots($root = NULL)
{
function drupal_phpunit_contrib_extension_directory_roots($root = NULL): array {
if ($root === NULL) {
$root = '/app/web';
}
$paths = [
$root . '/core/modules',
$root . '/core/profiles',
$root . '/core/themes',
$root . '/modules',
$root . '/profiles',
$root . '/themes',
Expand All @@ -68,7 +69,7 @@ function drupal_phpunit_contrib_extension_directory_roots($root = NULL)
$paths[] = is_dir("$path/profiles") ? realpath("$path/profiles") : NULL;
$paths[] = is_dir("$path/themes") ? realpath("$path/themes") : NULL;
}
return array_filter($paths, 'file_exists');
return array_filter($paths);
}

/**
Expand All @@ -80,38 +81,24 @@ function drupal_phpunit_contrib_extension_directory_roots($root = NULL)
* @return array
* An associative array of extension directories, keyed by their namespace.
*/
function drupal_phpunit_get_extension_namespaces($dirs)
{
$suite_names = ['Unit', 'Kernel', 'Functional', 'FunctionalJavascript'];
function drupal_phpunit_get_extension_namespaces($dirs) {
$namespaces = [];
foreach ($dirs as $extension => $dir) {
if (is_dir($dir . '/src')) {
// Register the PSR-4 directory for module-provided classes.
$namespaces['Drupal\\' . $extension . '\\'][] = $dir . '/src';
}
$test_dir = $dir . '/tests/src';
if (is_dir($test_dir)) {
foreach ($suite_names as $suite_name) {
$suite_dir = $test_dir . '/' . $suite_name;
if (is_dir($suite_dir)) {
// Register the PSR-4 directory for PHPUnit-based suites.
$namespaces['Drupal\\Tests\\' . $extension . '\\' . $suite_name . '\\'][] = $suite_dir;
}
}
// Extensions can have a \Drupal\extension\Traits namespace for
// cross-suite trait code.
$trait_dir = $test_dir . '/Traits';
if (is_dir($trait_dir)) {
$namespaces['Drupal\\Tests\\' . $extension . '\\Traits\\'][] = $trait_dir;
}
if (is_dir($dir . '/tests/src')) {
// Register the PSR-4 directory for PHPUnit-based suites.
$namespaces['Drupal\\Tests\\' . $extension . '\\'][] = $dir . '/tests/src';
}
}
return $namespaces;
}

// We define the COMPOSER_INSTALL constant, so that PHPUnit knows where to
// autoload from. This is needed for tests run in isolation mode, because
// phpunit.xml.dist is located in a non-default directory relative to the
// phpunit.xml is located in a non-default directory relative to the
// PHPUnit executable.
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
define('PHPUNIT_COMPOSER_INSTALL', '/app/web/autoload.php');
Expand All @@ -121,22 +108,23 @@ function drupal_phpunit_get_extension_namespaces($dirs)
* Populate class loader with additional namespaces for tests.
*
* We run this in a function to avoid setting the class loader to a global
* that can change. This change can cause unpredictable false positives for
* phpunit's global state change watcher. The class loader can be retrieved from
* that can change. This change can cause unpredictable false positives for the
* PHPUnit global state change watcher. The class loader can be retrieved from
* composer at any time by requiring autoload.php.
*/
function drupal_phpunit_populate_class_loader()
{
function drupal_phpunit_populate_class_loader() {

/** @var \Composer\Autoload\ClassLoader $loader */
$loader = require '/app/web/autoload.php';

// Start with classes in known locations.
$loader->add('Drupal\\BuildTests', '/app/web/core/tests');
$loader->add('Drupal\\Tests', '/app/web/core/tests');
$loader->add('Drupal\\TestSite', '/app/web/core/tests');
$loader->add('Drupal\\KernelTests', '/app/web/core/tests');
$loader->add('Drupal\\FunctionalTests', '/app/web/core/tests');
$loader->add('Drupal\\FunctionalJavascriptTests', '/app/web/core/tests');
$loader->add('Drupal\\TestTools', '/app/web/core/tests');

if (!isset($GLOBALS['namespaces'])) {
// Scan for arbitrary extension namespaces from core and contrib.
Expand All @@ -151,22 +139,15 @@ function drupal_phpunit_populate_class_loader()
}

return $loader;
};
}

// Do class loader population.
drupal_phpunit_populate_class_loader();

// Ensure we have the correct PHPUnit version for the version of PHP.
if (class_exists('\PHPUnit_Runner_Version')) {
$phpunit_version = \PHPUnit_Runner_Version::id();
} else {
$phpunit_version = Version::id();
}

// Set sane locale settings, to ensure consistent string, dates, times and
// numbers handling.
// @see \Drupal\Core\DrupalKernel::bootEnvironment()
setlocale(LC_ALL, 'C');
setlocale(LC_ALL, 'C.UTF-8', 'C');

// Set appropriate configuration for multi-byte strings.
mb_internal_encoding('utf-8');
Expand All @@ -178,25 +159,3 @@ function drupal_phpunit_populate_class_loader()
// and DST). This choice is made to prevent timezone related regressions and
// reduce the fragility of the testing system in general.
date_default_timezone_set('Australia/Sydney');

// Runtime assertions. PHPUnit follows the php.ini assert.active setting for
// runtime assertions. By default this setting is on. Ensure exceptions are
// thrown if an assert fails, but this call does not turn runtime assertions on
// if they weren't on already.
Handle::register();

// PHPUnit 4 to PHPUnit 6 bridge. Tests written for PHPUnit 4 need to work on
// PHPUnit 6 with a minimum of fuss.
if (version_compare($phpunit_version, '6.1', '>=')) {
class_alias('\PHPUnit\Framework\AssertionFailedError', '\PHPUnit_Framework_AssertionFailedError');
class_alias('\PHPUnit\Framework\Constraint\Count', '\PHPUnit_Framework_Constraint_Count');
class_alias('\PHPUnit\Framework\Error\Error', '\PHPUnit_Framework_Error');
class_alias('\PHPUnit\Framework\Error\Warning', '\PHPUnit_Framework_Error_Warning');
class_alias('\PHPUnit\Framework\ExpectationFailedException', '\PHPUnit_Framework_ExpectationFailedException');
class_alias('\PHPUnit\Framework\Exception', '\PHPUnit_Framework_Exception');
class_alias('\PHPUnit\Framework\MockObject\Matcher\InvokedRecorder', '\PHPUnit_Framework_MockObject_Matcher_InvokedRecorder');
class_alias('\PHPUnit\Framework\SkippedTestError', '\PHPUnit_Framework_SkippedTestError');
class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
class_alias('\PHPUnit\Util\Test', '\PHPUnit_Util_Test');
class_alias('\PHPUnit\Util\Xml', '\PHPUnit_Util_XML');
}
54 changes: 19 additions & 35 deletions tests/phpunit/phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
<?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="/app/tests/phpunit/bootstrap.php" colors="true"
<!-- Migrated for PHPUnit 11 (phpunit migrate-configuration). -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="/app/tests/phpunit/bootstrap.php"
colors="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutChangesToGlobalState="true">
<!-- TODO set printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter" once
https://youtrack.jetbrains.com/issue/WI-24808 is resolved. Drupal provides a
result printer that links to the html output results for functional tests.
Unfortunately, this breaks the output of PHPStorm's PHPUnit runner. However, if
using the command line you can add
- -printer="\Drupal\Tests\Listeners\HtmlOutputPrinter" to use it (note there
should be no spaces between the hyphens).
-->
beStrictAboutChangesToGlobalState="true"
failOnWarning="true"
cacheResult="false"
defaultTestSuite="govcms"
cacheDirectory=".phpunit.cache"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.5/phpunit.xsd">
<php>
<!-- Set error reporting to E_ALL. -->
<ini name="error_reporting" value="32767"/>
Expand All @@ -30,10 +24,6 @@
<env name="BROWSERTEST_OUTPUT_DIRECTORY" 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' -->
<!-- Example for changing the driver args to mink tests MINK_DRIVER_ARGS value: '["http://127.0.0.1:8510"]' -->
<!-- Example for changing the driver args to phantomjs tests MINK_DRIVER_ARGS_PHANTOMJS value: '["http://127.0.0.1:8510"]' -->
<!-- Example for changing the driver args to webdriver tests MINK_DRIVER_ARGS_WEBDRIVER value: '["firefox", null, "http://localhost:4444/wd/hub"]' -->
</php>
<testsuites>
<testsuite name="unit">
Expand All @@ -55,24 +45,18 @@
<directory>/app/tests/phpunit/tests</directory>
</testsuite>
</testsuites>
<listeners>
<!-- The Symfony deprecation listener has to come after the Drupal listener -->
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
</listener>
</listeners>
<!-- Filter for coverage reports. -->
<filter>
<whitelist>
<!-- Source for coverage reports. -->
<source>
<include>
<directory>/app/web/core/includes</directory>
<directory>/app/web/core/lib</directory>
<directory>/app/web/core/modules</directory>
<directory>/app/web/modules</directory>
<directory>/app/web/sites</directory>
<!-- By definition test classes have no tests. -->
<exclude>
<directory suffix="Test.php">./</directory>
<directory suffix="TestBase.php">./</directory>
</exclude>
</whitelist>
</filter>
</include>
<exclude>
<directory suffix="Test.php">./</directory>
<directory suffix="TestBase.php">./</directory>
</exclude>
</source>
</phpunit>