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
| Comment | File | Size | Author |
|---|---|---|---|
| #36 | simpletest-phpunit-correct-namespace-2465029-10843142-8.3.x-dev.patch | 4.3 KB | smashwini |
| #30 | 2465029-24.patch | 3.13 KB | r.nabiullin |
Comments
Comment #1
stefan.r commentedIt 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)
Comment #2
stefan.r commentedComment #3
stefan.r commentedComment #4
stefan.r commentedThis may need a followup to fix any occurrences of missing
parent::setUp();statements in customsetUp()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...Comment #5
dom. commentedRTBC+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.
Comment #6
stefan.r commentedContrib 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.
Comment #7
dom. commentedHi,
Unless I got it wrong, tests in Rules have for namespace Drupal\rules\Tests which seems normal. What did I miss ?
Comment #8
stefan.r commentedAre you looking in HEAD? I see
Drupal\Tests\rulesin all unit tests...http://cgit.drupalcode.org/rules/tree/tests/src/Unit?h=8.x-3.x
Comment #9
dom. commentedIndeed sorry
Comment #10
stefan.r commentedThis 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 :)
Comment #11
stefan.r commentedForgot to git add the actual test!
Comment #12
stefan.r commentedAnd a typo...
Comment #13
stefan.r commentedComment #14
stefan.r commentedMaybe the error message should be clarified?
"Under
Drupal\Tests" may lead people to think their tests need to be inDrupal\Testsspecifically, instead ofDrupal\Tests\modulenameComment #18
stefan.r commentedComment #19
dawehnerSure, this works, but I'm curious whether
\Drupal\Tests\Standards\DrupalStandardsListenermight be a better place? Maybe ask mile23 about it?Comment #20
stefan.r commentedActually 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.
Comment #21
stefan.r commentedComment #22
stefan.r commentedComment #24
mile23So 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. :-)
We really need a test of
checkValidNamespaceForTest()with some sample data so we know it complains about bad namespaces.That's not where the standards listener is, and we don't really need to autoload it this way.
Comment #25
mile23Weird. The tag renamed itself to 'undefined'.
Comment #26
Miguel.kode commentedThis is the re-roll for this patch. The next file has changed:
core/tests/bootstrap.php
Comment #27
Miguel.kode commentedSorry, I forgot the "Needs review" tag.
Comment #30
r.nabiullin commentedRerolled patch https://www.drupal.org/node/2465029#comment-9793051
Comment #31
andypostthis missed in last reroll
Comment #35
smashwini commentedAssigning myself to include the small changes mentioned in #31 by andypost.
Comment #36
smashwini commentedAdded below code in bootstrap.php and rerolled the patch in https://www.drupal.org/node/2465029#comment-9793051
Comment #37
smashwini commentedComment #39
mile23This 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.
Put this test in core/tests/Drupal/Listeners, right next to the listener.
Don't use @file.
Convert this to $this->setExpectedException(PHPUnit_Framework_ExpectationFailedException::class);
Convert this to use $this->setExpectedExceptionMessage().
drupal_phpunit_get_extension_namespaces() shouldn't do any of this.
drupal_phpunit_populate_class_loader() shouldn't do any of this, either. The listener is already registered. Basically, don't change bootstrap.php.
Comment #46
quietone commentedTriaging 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.