Monthly Archives: June 2014

AutoLoader Effect #2: Foreign Sources

I started experimenting with Selenium testcases. Therefor I wanted to use Extbase’s class “SeleniumBaseTestCase” as a root class for all my test cases. This wasn’t possible, because of AutoLoader Effect #1. The autoloader was not able to find this class, because it wasn’t part of Extbase’s “/Classes” directory and it also wasn’t mentioned in Extbase’s “/ext_autoload.php” file.

Well, thinking of AutoLoader Effect #1‘s solution, I simply added an according line to my own “/ext_autoload.php” file, in order to tell the autoloader where to find “SeleniumBaseTestCase”.


$extensionClassesPath = t3lib_extMgm::extPath('csevents') . 'Classes/';
return array(
    'tx_extbase_tests_seleniumbasetestcase' => t3lib_extMgm::extPath('extbase') . 'Tests/SeleniumBaseTestCase.php',
    'tx_csevents_tests_unit_domain_repository_repositorybasetestcase' => $extensionClassesPath . '../Tests/Unit/Domain/Repository/RepositoryBaseTestCase.php',
);

Effect: None – same error, the class cannot be found by the autoloader.

Reason: The autoloader splits the class name, it is searching for, by “_” and searches for the second part, which holds the extension name (“extbase” or “csevents” in my cases). Afterwards it searches for the “ext_autoload.php” file in the extension’s root directory. Thus, searching for “Tx_Extbase_…” makes the autoloader search for “ext_autoload.php” in the “extbase” directory, “my” ext_autoload is never used while searching for “Tx_Extbase_…”. Even if I define the correct solution, the autoloader will never listen to it. Line #3 has absolutly no effect as long as it is not part of the “extbase” extension. 🙁

Solution: None by myself. The extension itself (extbase in this case) has to define all necessary autoload-entries. In this particular case, I was glad that “SeleniumBaseTestCase” is a 1:1 extension of “tx_phpunit_selenium_testcase”, which can be found easily by the autoloader. Thus I used that one. Not nice, but successfull.


<?php

/**
* Base Selenium testcase for the Extbase extension.
*/
abstract class Tx_Extbase_SeleniumBaseTestCase extends tx_phpunit_selenium_testcase {
}
?>

AutoLoader effect #1: “/Tests” Folder

There are some effects of the Extbase AutoLoader, you shall be aware of when writing unit tests.

Testing the repository, I defined a “RepositoryBaseTestCase” which holds common functionality for all 4 repository tests. Simple. Problem: The autoloader was not able to find this class when I tried to extend it.

class Tx_Csevents_Tests_Unit_Domain_Repository_AppointmentRepositoryTest extends Tx_Csevents_Tests_Unit_Domain_Repository_RepositoryBaseTestCase {
}

The base class “Tx_Csevents_Tests_Unit_Domain_Repository_RepositoryBaseTestCase” is on the same directory, but the autoloader is not able to find it. Whenever I try to run the tests, I get the error message “Fatal error: Class ‘Tx_Csevents_Tests_Unit_Domain_Repository_RepositoryBaseTestCase’ not found in /home/.sdb/var/www/html/dummy-4.5.32/typo3conf/ext/csevents/Tests/Unit/Domain/Repository/AppointmentRepositoryTest.php on line 37” Why is that? Simply, it’s because my unit tests are not stored underneath “/Classes”, but underneath “/Tests” (you see the referred base class on the bottom of the screenshot).

screenshot1The autoloader recongnises classes in the “/Classes” folder only, thus it doesn’t find the “RepositoryBaseTestCase.php” when I refer to it as “Tx_Csevents_Tests_Unit_Domain_Repository_RepositoryBaseTestCase”.

Solution: Help the autoloader and give it a file “/ext_autoload.php”:

screenshot2


<?php

$extensionClassesPath = t3lib_extMgm::extPath('csevents') . 'Classes/';
return array(
    'tx_csevents_tests_unit_domain_repository_repositorybasetestcase' => $extensionClassesPath . '../Tests/Unit/Domain/Repository/RepositoryBaseTestCase.php',
);

?>

Now the autoloader knows where to search for the referred class. Please note that you have to use lowercase letters for the array keys until Typo3 4.5.x including.

Using the “extensionClassesPath” with the trailing “Classes/” directory, which is removed by the “../” in the array again, is a little strange. I just used it, because this annotation is used commonly. It reflects the view of the autoloader, which is using “Classes” as it’s base directory to start searching. You may change this, if you feel better then. 😉

You could have done a simple “require_once” instead of all this stuff, but this is forbidden by the coding guidelines. Thus this is the official and nice solution.

The Wow-Effect

Well, if you read my former post, you will find out that I was out of business for weeks. Taking it in another way: I totally forgot what I did in the last minutes before changing systems and going offline.

So now I came back and was a little frightened about my “wake-up from standby” or “recall” of what happened in my project and what’s to be done next. And suddenly I had the “Wow-Effect”: MyLyn and Bugzilla told me exactly, what to do next. MyLyn also highlighted the sourcesfiles for me and SVN showed me, which files I handled last. “Recall” was no problem any more.

And then “Wow-Effect” part 2 striked me with fortunate and happy surprise: I decided to do some finger-exercise in the first place and to change all integer timestamps to DateTime objects. In the past I would have struggled for hours by thinking and thinking again about all side-effects and consequences and if all might work successfully when I use the refacored software the first time. But now I simply klicked the “Test” button, found some defects, handled them and had an “all green” state just after one hour. Perfect!

Once again: Effect #1: You find and handle the defects as early (=as cheap) as possible. effect #2: You are sure that your software is working properly, thus you can erase this task from MyLyn und from your mind and go on with new tasks completly free of any doubts. Life is so easy. 😀

Thus DO YOUR INVESTMENT IN THE BEGINNING, DO YOUR UNIT-TESTS, IT WILL MAKE YOU GLAD JUST IN THE MINUTE YOU (FREQUENTLY) USE IT! And: YOU WILL USE IT FREQUENTLY, BECAUSE IT’S SO SIMPLE AND MAKES YOU HAPPY!