Follow-up to #2464817: A few PHPUnit tests are not in the correct namespace where @Berdir said:

If we want to enforce that unit tests are in \Drupal\Tests (and I think we want), then I think we should do it explicitly and find a way to make them fail, not just display a confusing error that isn't detected by the testing system :)

Problem/Motivation

Not having tests in the Drupal\Tests namespace can give "Found no database prefix for test ID" errors (see PHP7 meta issue, SQLite tests and #2464817: A few PHPUnit tests are not in the correct namespace). However it seems D.org testbots don't catch these somehow.

Proposed resolution

Enforce unit tests to be in the Drupal\Tests namespace.

Remaining tasks

Review patch

User interface changes

N/A

API changes

Unit tests must be in \Drupal\Tests

Comments

stefan.r’s picture

Status: Active » Needs review
StatusFileSize
new1.28 KB

It seems not all unit tests explicitly call parent::setUp(), but that's another issue... (ie. core/tests/Drupal/Tests/Component/Utility/UnicodeTest.php doesn't)

stefan.r’s picture

Status: Needs review » Needs work
StatusFileSize
new684 bytes
stefan.r’s picture

Issue summary: View changes
Status: Needs work » Needs review
Related issues: +#2454439: [META] Support PHP 7
stefan.r’s picture

This may need a followup to fix any occurrences of missing parent::setUp(); statements in custom setUp() methods.

If we think people will keep forgetting these, maybe we should throw an exception if the UnitTestCase::setUp() method hasn't run? Alternatively we could do all "necessary" logic (such as the one in this issue) in the constructor...

dom.’s picture

Status: Needs review » Reviewed & tested by the community

RTBC+1 for me as is.
However, two (probably stupid) questions :
- Does'nt this means that unit tests from contrib modules will always throw exceptions because they won't be in Drupal\Tests namespace ?
- I'm not sure if we can but can't this be UnitTested ? This is a bit test-ception but could be nice to validate this expected behavior.

stefan.r’s picture

Contrib tests should also be in Drupal\Tests, see the Rules module for an example.

This can be tested by creating a test file that is in the wrong namespace and wrapping the parent::setUp() call in a try/catch block.

dom.’s picture

Hi,
Unless I got it wrong, tests in Rules have for namespace Drupal\rules\Tests which seems normal. What did I miss ?

stefan.r’s picture

Are you looking in HEAD? I see Drupal\Tests\rules in all unit tests...

http://cgit.drupalcode.org/rules/tree/tests/src/Unit?h=8.x-3.x

dom.’s picture

Indeed sorry

stefan.r’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new1.17 KB

This adds a unit test. I didn't see a way of testing for this without wrecking our wonderful directory structure, hope this won't hurt any feelings :)

stefan.r’s picture

StatusFileSize
new2.33 KB

Forgot to git add the actual test!

stefan.r’s picture

StatusFileSize
new2.33 KB

And a typo...

stefan.r’s picture

Issue summary: View changes
stefan.r’s picture

Issue summary: View changes

Maybe the error message should be clarified?

"Under Drupal\Tests" may lead people to think their tests need to be in Drupal\Tests specifically, instead of Drupal\Tests\modulename

The last submitted patch, 10: 2465029-10.patch, failed testing.

The last submitted patch, 11: 2465029-11.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 12: 2465029-12.patch, failed testing.

stefan.r’s picture

Status: Needs work » Needs review
StatusFileSize
new2.33 KB
dawehner’s picture

+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -42,6 +42,11 @@ protected function setUp() {
+
+    // Ensure that tests are in the Drupal\Tests namespace.
+    if (__NAMESPACE__ != 'Drupal\Tests' && strpos(__NAMESPACE__, 'Drupal\Tests\\', 0) !== 0) {
+      throw new \Exception('Unit tests must be in the "Drupal\Tests" namespace.');
+    }

Sure, this works, but I'm curious whether \Drupal\Tests\Standards\DrupalStandardsListener might be a better place? Maybe ask mile23 about it?

stefan.r’s picture

StatusFileSize
new3.13 KB

Actually it does seem like a better place, this is about checking standards after all. And it also executes when people forget to run UnitTestCase::setUp() :)

What would be useful is an issue summary update with why exactly we want tests to be in Drupal\Tests. Moreso as we'll have to break that convention for our meta-test (unless we were to mock the endTest() method).

I understand it's more "tidy", but another problem seems to be that we get a test script error under certain circumstances, it would be good to check the PHP error log and find out what is behind that test runner error.

stefan.r’s picture

StatusFileSize
new2.49 KB
new3.78 KB
stefan.r’s picture

StatusFileSize
new3.68 KB

joelpittet queued 22: 2465029-22.patch for re-testing.

mile23’s picture

Version: 8.0.x-dev » 8.1.x-dev
Status: Needs review » Needs work
Issue tags: +undefined

So I guess the idea here is that you can have a listener that does a couple of things:

1) As you rush to write more and more unit tests in a haze of coding frenzy, if you forget to namespace your test properly, this reminds you. The test is discovered and run, but this burps and lets you know you're in the wrong.

2) We have a nice fence against changes to the test discovery system finding non-Drupal tests.

Here's a review of what's here. It needs a re-roll so I'm not working too hard at this. :-)

  1. +++ b/core/tests/Drupal/DrupalStandardsListenerTest/DrupalStandardsListenerTest.php
    @@ -0,0 +1,35 @@
    +  public function testEndTest() {
    

    We really need a test of checkValidNamespaceForTest() with some sample data so we know it complains about bad namespaces.

  2. +++ b/core/tests/bootstrap.php
    @@ -70,6 +70,7 @@ function drupal_phpunit_register_extension_dirs(Composer\Autoload\ClassLoader $l
    +$loader->add('Drupal\\DrupalStandardsListenerTest', __DIR__);
    

    That's not where the standards listener is, and we don't really need to autoload it this way.

mile23’s picture

Issue tags: -undefined +Needs reroll

Weird. The tag renamed itself to 'undefined'.

Miguel.kode’s picture

StatusFileSize
new3.76 KB

This is the re-roll for this patch. The next file has changed:

core/tests/bootstrap.php

Miguel.kode’s picture

Status: Needs work » Needs review

Sorry, I forgot the "Needs review" tag.

Status: Needs review » Needs work

The last submitted patch, 26: 2465029-23.patch, failed testing.

The last submitted patch, 26: 2465029-23.patch, failed testing.

r.nabiullin’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new3.13 KB
andypost’s picture

Status: Needs review » Needs work
+++ b/core/tests/bootstrap.php
@@ -97,6 +97,10 @@ function drupal_phpunit_get_extension_namespaces($dirs) {
+// Start with classes in known locations.
+$loader = require __DIR__ . '/../../autoload.php';
+$loader->add('Drupal\\Tests', __DIR__);
+$loader->add('Drupal\\DrupalStandardsListenerTest', __DIR__);

this missed in last reroll

The last submitted patch, 30: 2465029-24.patch, failed testing.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

smashwini’s picture

Assigned: Unassigned » smashwini

Assigning myself to include the small changes mentioned in #31 by andypost.

smashwini’s picture

Added below code in bootstrap.php and rerolled the patch in https://www.drupal.org/node/2465029#comment-9793051

+++ b/core/tests/bootstrap.php
@@ -97,6 +97,10 @@ function drupal_phpunit_get_extension_namespaces($dirs) {
+// Start with classes in known locations.
+$loader = require __DIR__ . '/../../autoload.php';
+$loader->add('Drupal\\Tests', __DIR__);
+$loader->add('Drupal\\DrupalStandardsListenerTest', __DIR__);
smashwini’s picture

Assigned: smashwini » Unassigned
Status: Needs work » Needs review

Status: Needs review » Needs work
mile23’s picture

Version: 8.3.x-dev » 8.2.x-dev

This is a testing improvement, so it can go into 8.2.x, though it might end up being disruptive if we find tests in the wrong namespaces.

The patch applies to either branch.

  1. --- /dev/null
    +++ b/core/tests/Drupal/DrupalStandardsListenerTest/DrupalStandardsListenerTest.php
    

    Put this test in core/tests/Drupal/Listeners, right next to the listener.

  2. +++ b/core/tests/Drupal/DrupalStandardsListenerTest/DrupalStandardsListenerTest.php
    @@ -0,0 +1,35 @@
    +/**
    + * @file
    + * Contains \Drupal\UnitTestCaseTest\UnitTestCaseTest.
    + */
    

    Don't use @file.

  3. +++ b/core/tests/Drupal/DrupalStandardsListenerTest/DrupalStandardsListenerTest.php
    @@ -0,0 +1,35 @@
    +   * @expectedException PHPUnit_Framework_ExpectationFailedException
    

    Convert this to $this->setExpectedException(PHPUnit_Framework_ExpectationFailedException::class);

  4. +++ b/core/tests/Drupal/DrupalStandardsListenerTest/DrupalStandardsListenerTest.php
    @@ -0,0 +1,35 @@
    +   * @expectedExceptionMessage Test is not in the Drupal\Tests namespace.
    

    Convert this to use $this->setExpectedExceptionMessage().

  5. +++ b/core/tests/bootstrap.php
    @@ -77,6 +77,11 @@ function drupal_phpunit_contrib_extension_directory_roots($root = NULL) {
     function drupal_phpunit_get_extension_namespaces($dirs) {
    +  // Start with classes in known locations.
    +  $loader = require __DIR__ . '/../../autoload.php';
    +  $loader->add('Drupal\\Tests', __DIR__);
    +  $loader->add('Drupal\\DrupalStandardsListenerTest', __DIR__);
    +
    

    drupal_phpunit_get_extension_namespaces() shouldn't do any of this.

  6. +++ b/core/tests/bootstrap.php
    @@ -108,6 +113,10 @@ function drupal_phpunit_get_extension_namespaces($dirs) {
     function drupal_phpunit_populate_class_loader() {
    +// Start with classes in known locations.
    +$loader = require __DIR__ . '/../../autoload.php';
    +$loader->add('Drupal\\Tests', __DIR__);
    +$loader->add('Drupal\\DrupalStandardsListenerTest', __DIR__);
     
       /** @var \Composer\Autoload\ClassLoader $loader */
       $loader = require __DIR__ . '/../../autoload.php';
    

    drupal_phpunit_populate_class_loader() shouldn't do any of this, either. The listener is already registered. Basically, don't change bootstrap.php.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

quietone’s picture

Component: simpletest.module » phpunit

Triaging issues in simpletest.module as part of the Bug Smash Initiative to determine if they should be in the Simpletest Project or core.

This looks like it a Phpunit issue, changing component.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.