Namespaces should group code that logically and semantically belong together. In my mind, configurations, routers, and tests all belong together as part of the application as a whole, and thus my configurations tend to have them all share namespace:
autoload: { "psr-4": { "Vendor\\Package\\": [ "public", "conf", "src" ] } }
autoload-dev: { "psr-4": { "Vendor\\Package\\": [ "tests" ] } }
Of course, by sharing namespaces, that means each artifact has to be classified (often by its "kind") to prevent class name collisions. For example, Vendor\Package\Foo
might involve the following related artifacts:
Vendor\Package\FooTest
, the unit test for foo in tests/FooTest.php
Vendor\Package\FooIntegrationTest
, an integration test specifically covering foo in tests/FooIntegrationTest.php
Vendor\Package\AbstractFoo
, the base for family members of foo in src/AbstractFoo.php
Vendor\Package\Fooable
, the interface for foo kind of things in src/Fooable.php
Along these lines, you might consider separating out your different kinds of code into different directories, rather than one "catch-all" src
. For large projects, this makes finding particular kinds of files easier, but is likely overkill for libraries or small applications:
autoload: {
"psr-4": {
"Vendor\\Package\\": [
"public", "conf", "lib", "view", "contract", "exception"
]
}
}
As for "convention", I particularly find sharing namespaces between source code and tests to be convenient and easy, because when I want to test Foo I don't have to juggle namespaces to get at it.
// tests/Something/FooTest.php
namespace Vendor\Package\Test\Something;
use Vendor\Package\Test\BaseTestCase;
use Vendor\Package\Something\Foo; // extra work I don't want to do
class FooTest extends BaseTestCase {
public function testX() {
$sut = new Foo;
}
}
One extra line in every test file, plus the cognitive load of having to find the SUT when writing a test meant more work for writing tests, which lowered my desire to write tests. So, you might say that sharing namespaces between source and tests lowers the barriers to writing tests.
In the end, questions of source code organization really fall to each project to establish a layout that promotes efficient development and reasonable builds. I'd say it can't hurt to try one, and refactor if it's not working out.