During normal site operation, namespaces of disabled modules are not registered with the autoloader. This means if a module tries to instantiate a class provided by a disabled module, an error is (correctly) thrown.
However, during testing, simpletest.module registers the namespaces of all disabled modules in order to find their tests. This means that if a module has the error mentioned above, then it will not be discovered by the test.
In #1780396-54: Namespaces of disabled modules are registered during test runs, @Berdir suggested to fix this by limiting simpletest to only register the Tests
subnamespace of each module. However, in that issue, @sun raised concerns about that making unit test writing too cumbersome (since in unit tests, there's no concept of enabling modules).
Comment | File | Size | Author |
---|---|---|---|
#9 | 2006476_9.patch | 1.8 KB | Mile23 |
#1 | simpletest-2006476-1.patch | 1.6 KB | effulgentsia |
Comments
Comment #1
effulgentsia CreditAttribution: effulgentsia commented#1780396-36: Namespaces of disabled modules are registered during test runs (the latest patch in that issue) has many hunks that no longer apply. This patch just takes the key hunk from that patch. It will likely fail, since it doesn't include all the other hunks.
Comment #2
effulgentsia CreditAttribution: effulgentsia commentedThis hack was necessary to make the
exclude
directives incore/phpunit.xml.dist
actually work. Without that, PHPUnit tries to load classes that aren't actually tests, causing #1 to fail before even running any tests. If someone knows the correct way to fix that (i.e., without hacking PHPUnit), please share.Comment #3.0
(not verified) CreditAttribution: commenteds/this/that/
Comment #9
Mile23In run-tests.sh,
simpletest_script_init()
always creates aTestRunnerKernel
, which sets up enough services so that we can store test results to a database. TRK needs the simpletest module, and says this:$this->getContainer()->get('test_discovery')->registerTestNamespaces();
which autoloads all the namespaces.run-tests.sh then makes a child proc and calls itself with
--execute-test
which is a special mode to only run the test and not do discovery. If the test is a WTB test, then it runs, so all the extraneous classes are autoloadable. But if it's a PHPUnit-based test, it eventually reachessimpletest.module::simpletest_phpunit_run_command()
, which callsexec()
to run the phpunit test runner, and that's isolated from the autoloading present in under run-tests.sh.Under PHPUnit, we do some special-case class loading in
core/tests/bootstrap.php::drupal_phpunit_get_extension_namespaces()
. This only loads the test namespaces you'd expect for core and extensions. Later, when we get to theBrowserTestBase
layer, we end up autoloading for uninstalled modules. That's because BTB usesTestRunnerKernel
as the kernel under test.KernelTestBase
does not useTestRunnerKernel
, so it doesn't suffer this fate.So if the goal is to disallow autoloading of uninstalled or unneeded modules, then the first place to look is
TestRunnerKernel
and it's reliance on simpletest andTestDiscovery
, sinceTestDiscovery::registerTestNamespaces()
is where all this extra autoloading is enabled.We should figure out how to perform test discovery and autoloading without 'enabling' any modules, including simpletest. And that's why this issue is related to #2945465: Make TestDiscovery find info we need, not info we don't need
Here are some tests which show that functional tests autoload simpletest module when they don't need to, and that other PHPUnit-based tests don't.
Comment #19
nevergone CreditAttribution: nevergone as a volunteer commentedRelated contrib project:
https://www.drupal.org/project/tecla
Comment #20
Mile23Updates to #9: Simpletest isn't in core any more, so therefore it is not enabled. :-) CR: https://www.drupal.org/node/3112907
The road to a solution still lives in
TestRunnerKernel
.