[TYPO3-dev] PHPUnit cache?

Helmut Hummel helmut.hummel at typo3.org
Mon Dec 2 13:34:39 CET 2013


Hi François,

On 27.11.13 17:22, François Suter wrote:

>> /Users/fsuter/Sites/foo/typo3conf/ext/foo/Tests/Calculation/CalculationTest.php
>>
>> (not in Tests/Unit/ like AnnualizedPerformanceTest.php)
>
> That did it.
>
> I was also kind of surprised to put the tests in the "Unit" subfolder,

This is a convention to better separate unit test cases from functional 
test cases. Unit tests should reside in Tests/Unit/... and functional 
tests in Tests/Functional/...

> but I actually followed the structure created by the Extension Builder
> for default test classes for domain models.

This is fine, if the tests then are unit tests (testing only small code 
units of a class).

> But it had really weird effects all around. On top of the problem
> discussed here, I found out that if I added "Unit/" in the namespace, i.e.
>
> namespace Cobweb\Foo\Tests\Unit\Calculation;
>
> PphStorm would not resolve the name of the base class.

PhpStorm sometimes chokes when renaming namespaces. If everything is 
correct and PhpStorm does not resolve classes correctly, closing and 
reopening PhpStorm always worked for me.

> Maybe part of the mess is due to the namespace declared in the domain
> model test classes, which is just
>
> namespace Cobweb\Foo\Tests;

Yes, this it not optimal and Steffen already fixed it.

> Again, this seems to be the default output by the Extension Builder. I
> don't know if it's a good idea, nor how namespaces and file paths are
> actually resolved in such cases. The sure is that they don't match, but
> that does not seem to bother phpunit.
>
> Anyway moving the test classes around worked, thanks for the suggestion.
> There's still some black magic going on, but I'm going to ignore it for
> now, as it is not critical.

Not too much magic in place. It boils down to only one rule:

=====
If your class namespace and name matches the file location and name, 
this class will be autoloaded when needed without any additional 
configuration (since 6.0)
=====

This implies: If your class namespace and name does not match the file 
location, you either need to require the class file manually or 
configure it in the class loader registry (ext_autoload.php), before you 
can use it.

How to match namespace and file location (for Extensions)?

1. The *first segment* of the namespace is *always* a (free to choose) 
vendor name written in *UpperCamelCase*. Besides these two mandatory 
things, the vendor name is completely arbitrary and will be ignored 
during class loading.

2. The *second segment* must be the extension key, while underscores 
must be translated to camel casing (Extkey "foo_bar_baz" must be 
"FooBarBaz" as second namespace segment)

3. The following segments of the namespace must match exactly the 
directory structure of the class file, while it has to be distinguished 
between test classes and application classes

3a) Application Classes reside in a (top level) "Classes" folder and the 
"Classes" folder will *not* be part of the namespace
e.g. A class with the namespace "\Vendor\FooBarBaz\Bla" must reside in 
the directory: foo_bar_baz/Classes/Bla/ (and vice versa)

3b) Test Classes reside in a (top level) "Tests" folder and the "Tets" 
folder *must* be part of the namespace
e.g. A test class in the directory: foo_bar_baz/Tests/Unit/Bla/ must 
have the namespace "\Vendor\FooBarBaz\Tests\Unit\Bla" (and vice versa)

4. The file name must match exactly the class name (including casing) 
with an appended ".php" file extension
e.g. a fully qualified class name "\Vendor\FooBarBaz\Bla\Blupp" must 
have a class file at exactly this location: 
"foo_bar_baz/Classes/Bla/Blupp.php"


Maybe this more detailed info can be added to the docs here:

http://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Namespaces/Index.html#namespaces-extensions


This information combined with the fact that the phpunit library 
includes test case files manually explains why test case classes could 
have inconsistent (or no) namespace, but if the tests themselves 
instantiate classes, these classes *must* match the convention described 
above to be found without a manual include in the test case.


Hope this explains the behaviour you experienced a bit more detailed.

Kind regards,
Helmut

-- 
Helmut Hummel
Release Manager TYPO3 6.0
TYPO3 Core Developer, TYPO3 Security Team Member

TYPO3 .... inspiring people to share!
Get involved: typo3.org



More information about the TYPO3-dev mailing list