Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 295999

[Needs change record updates] Align TestDiscovery and bootstrap.php's non-permissive loading of PSR-4 namespaces for traits

$
0
0

Problem/Motivation

tl;dr

Currently, if you run core's phpunit-based tests using phpunit, it will find and load traits for tests in contrib modules. If you do the same thing using TestDiscovery, it won't. That's because TestDiscovery currently only allows specific namespaces per module per test type, without allowing autoloading of the whole of the test namespace. So for instance if you have a Unit test and a Functional test and you define a trait for both of them to use, then TestDiscovery won't allow for autoloading that trait.

That's the problem we're trying to solve in this issue, in harmony with the principles in #123.

The solution is that we have TestDiscovery register the whole test namespace for autoloading, which creates a new problem: This allows autoloading of tests which don't fit into the categories core knows how to run.

My early solution to that problem was to throw an exception. @Torenware kept the exception, but added a category for 'Unclassified' that could be used for non-Core modules; the exceptions enforced the new set-up for Core, but not for Contrib. @alexpott added a test suite for 'unclassified', which puts some edges on where these unclassified tests should be in the file system; this approach treats Core and Contrib the same.


While factoring a complicated set of mocks for the file_example module in Examples, I've discovered that run-tests.sh cannot find a trait that is in the Drupal\Tests when the trait is used in a PHPUnit test. The same tests run fine if run directly via ../vendor/bin/phpunit.

I've put together a demo that shows the problem. The test module lays out its files as so:

test_traits_in_tests/
├── src
│   └── NotTestTrait.php
├── test_traits_in_tests.info.yml
├── test_traits_in_tests.module
└── tests
    └── src
        ├── TestTrait.php
        └── Unit
            ├── AnotherTrivialTest.php
            └── TrivialTest.php

TrivialTest uses TestTrait, and AnotherTrivialTest uses NotTestTrait. Except for their namespacing and use statements the two tests and the two traits are identical.

Running phpunit from the command line:

vagrant@drupalvm3:/var/www/drupal/core$ ../vendor/bin/phpunit ../modules/custom/test_traits_in_tests/
PHPUnit 4.8.11 by Sebastian Bergmann and contributors.

..

Time: 23.53 seconds, Memory: 6.75Mb

OK (2 tests, 2 assertions)

Using run-test.sh, however, TrivialTest crashes:

vagrant@drupalvm3:/var/www/drupal/core$ php scripts/run-tests.sh --url http://192.168.88.42/drupal/ --module test_traits_in_tests

Drupal test run
---------------

Tests to be run:
  - Drupal\Tests\test_traits_in_tests\Unit\AnotherTrivialTest
  - Drupal\Tests\test_traits_in_tests\Unit\TrivialTest

Test run started:
  Saturday, October 31, 2015 - 22:04

Test summary
------------

Drupal\Tests\test_traits_in_tests\Unit\AnotherTrivialTest      1 passes
PHP Fatal error:  Trait 'Drupal\Tests\test_traits_in_tests\TestTrait' not found in /var/www/drupal/modules/custom/test_traits_in_tests/tests/src/Unit/TrivialTest.php on line 22
PHP Stack trace:
PHP   1. {main}() /var/www/drupal/core/scripts/run-tests.sh:0
PHP   2. simpletest_script_run_one_test() /var/www/drupal/core/scripts/run-tests.sh:42
PHP   3. spl_autoload_call() /var/www/drupal/core/scripts/run-tests.sh:649
PHP   4. Symfony\Component\ClassLoader\ApcClassLoader->loadClass() /var/www/drupal/core/scripts/run-tests.sh:0
PHP   5. require() /var/www/drupal/vendor/symfony/class-loader/ApcClassLoader.php:114

Fatal error: Trait 'Drupal\Tests\test_traits_in_tests\TestTrait' not found in /var/www/drupal/modules/custom/test_traits_in_tests/tests/src/Unit/TrivialTest.php on line 22

Since factoring tests is a good thing, we ought to support this.

Proposed resolution

Currently our bootstrap.php for PHPunit autoloads from tests/src whereas simpltest's TestDiscovery autoloads from tests/src/FunctionalJavascript, tests/src/Functional, tests/src/Kernel, and tests/src/Unit. In order to support traits anywhere in tests/src we need to change TestDiscovery to work the same way as PHPunit's bootstrap.php. Once TestDiscovery can autoload from tests/src we have an additional issue - tests outside the 4 testsuites will be discovered. To handle this we introduce a new namespace called Traits.

We adopt a policy where test traits belong in tests/src/Traits, and this namespace is always autoloaded along with any of the test suite namespaces.

  1. PHPUnit's test runner, run-tests.sh and the Simpletest UI should all work in as similar a way as possible.
  2. It has to be possible to only run tests of a certain type. Lumping unit, functional and functional javascript tests together is a bad idea because they have different test infrastructure requirements.
  3. Users should be able to get all a module's tests to run with run-test.sh --module MODULE_NAME
  4. Running with run-test.sh --directory MODULE_DIRECTORY and ./vendor/bin/phpunit -c ./core/phpunit.xml.dist MODULE_DIRECTORY should result in running all the same PHPUnit based tests. (run-tests should also run the simpletest tests) These should also be the same tests when using the --module option.
  5. Running with ./vendor/bin/phpunit -c ./core/phpunit.xml.dist --filter MODULE_NAME should also run all the module's tests

See #198 for more discussion of the solution.

Remaining tasks

User interface changes

None.

API changes

Trait classes must be moved to the Traits namespace.

Data model changes

None.


Viewing all articles
Browse latest Browse all 295999

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>