czukowski / I18n_Plural

I18n module for grammatically correct plural inflections, and maybe even some extra features related to i18n.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tests failing when run them for whole kohana with I18n_Plural installed

ValerchikV opened this issue · comments

I use
phpunit --bootstrap=modules/unittest/bootstrap.php modules/unittest/tests.php;
command provided in kohana docs to test kohana and installed modules.

But with I18n_Plural installed it fail to run tests with errors
`
2012-11-19 15:07:54 --- EMERGENCY: ErrorException [ 1 ]: Class 'I18n\Testcase' not found ~ MODPATH/I18n/tests/I18n/CoreTest.php [ 16 ] in :
2012-11-19 15:07:54 --- DEBUG: #0 [internal function]: Kohana_Core::shutdown_handler()
#1 {main} in :

2012-11-19 15:13:41 --- EMERGENCY: ErrorException [ 1 ]: Class 'I18n\Plural\Testcase' not found ~ MODPATH/I18n/tests/I18n/Plural/ArabicTest.php [ 25 ] in :
2012-11-19 15:13:41 --- DEBUG: #0 [internal function]: Kohana_Core::shutdown_handler()
#1 {main} in :

`

If i do require_once 'Testcase.php'; in this files it will fail with error

PHP Notice: Constant EXT already defined in /mnt/hgfs/ipnew/modules/I18n/tests/I18n/kohana.php on line 3 PHP Notice: Constant DOCROOT already defined in /mnt/hgfs/ipnew/modules/I18n/tests/I18n/kohana.php on line 4 PHP Notice: Constant APPPATH already defined in /mnt/hgfs/ipnew/modules/I18n/tests/I18n/kohana.php on line 5 PHP Notice: Constant MODPATH already defined in /mnt/hgfs/ipnew/modules/I18n/tests/I18n/kohana.php on line 6 PHP Notice: Constant SYSPATH already defined in /mnt/hgfs/ipnew/modules/I18n/tests/I18n/kohana.php on line 7 PHP Fatal error: Cannot redeclare class Kohana_Core in /mnt/hgfs/ipnew/system/classes/Kohana/Core.php on line 16

think this is because you use your own bootstrap

I`m using latest kohana 3.3.0 - possible this is because they updated work with their phpunit module

This is definitely the cause. I needed the bootstrap to load a couple more files, because Kohana autoloader didn't use the 'tests' folders.

"Cannot redeclare class Kohana_Core" means that 'kohana.php', which is basically a copy of Kohana bootstrap, has also got included.

Basically, only these extra files need to be required (I think):

  • helpers.php
  • Testcase.php
  • Plural/Testcase.php

I would like to get rid of 'kohana.php' completely, but I need the tests to also work independently on all tests and I can't see how to address this now.

Can you suggest anything?

kohana test runner do search of ALL files in test folder and include_once them one by one
What it find looks like this:

  'tests/I18n' => 
  array (
    'tests/I18n/CoreTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/CoreTest.php',
    'tests/I18n/Date' => 
    array (
      'tests/I18n/Date/FormatTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Date/FormatTest.php',
    ),
    'tests/I18n/DateTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/DateTest.php',
    'tests/I18n/KohanaTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/KohanaTest.php',
    'tests/I18n/Plural' => 
    array (
      'tests/I18n/Plural/ArabicTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/ArabicTest.php',
      'tests/I18n/Plural/BalkanTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/BalkanTest.php',
      'tests/I18n/Plural/BretonTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/BretonTest.php',
      'tests/I18n/Plural/ColognianTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/ColognianTest.php',
      'tests/I18n/Plural/CzechTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/CzechTest.php',
      'tests/I18n/Plural/FrenchTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/FrenchTest.php',
      'tests/I18n/Plural/GaelicTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/GaelicTest.php',
      'tests/I18n/Plural/HebrewTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/HebrewTest.php',
      'tests/I18n/Plural/IrishTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/IrishTest.php',
      'tests/I18n/Plural/LangiTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/LangiTest.php',
      'tests/I18n/Plural/LatvianTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/LatvianTest.php',
      'tests/I18n/Plural/LithuanianTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/LithuanianTest.php',
      'tests/I18n/Plural/MacedonianTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/MacedonianTest.php',
      'tests/I18n/Plural/MalteseTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/MalteseTest.php',
      'tests/I18n/Plural/ManxTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/ManxTest.php',
      'tests/I18n/Plural/NoneTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/NoneTest.php',
      'tests/I18n/Plural/OneTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/OneTest.php',
      'tests/I18n/Plural/PolishTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/PolishTest.php',
      'tests/I18n/Plural/RomanianTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/RomanianTest.php',
      'tests/I18n/Plural/SlovenianTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/SlovenianTest.php',
      'tests/I18n/Plural/TachelhitTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/TachelhitTest.php',
      'tests/I18n/Plural/TamazightTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/TamazightTest.php',
      'tests/I18n/Plural/Testcase.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/Testcase.php',
      'tests/I18n/Plural/TwoTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/TwoTest.php',
      'tests/I18n/Plural/WelshTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/WelshTest.php',
      'tests/I18n/Plural/ZeroTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Plural/ZeroTest.php',
    ),
    'tests/I18n/Reader' => 
    array (
      'tests/I18n/Reader/KohanaTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Reader/KohanaTest.php',
    ),
    'tests/I18n/Testcase.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/Testcase.php',
    'tests/I18n/ValidationTest.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/ValidationTest.php',
    'tests/I18n/bootstrap.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/bootstrap.php',
    'tests/I18n/generate_factory.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/generate_factory.php',
    'tests/I18n/helpers.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/helpers.php',
    'tests/I18n/kohana.php' => '/mnt/hgfs/ipnew/modules/I18n/tests/I18n/kohana.php',
  ),

Having additional files is very bad - user will be unable to run only 1 test if need because test useless without additional files. Also this files will be included by test runner and this will cause errors.
To resolve issue with additional files i propose you to create abstract base class wich will extend Unittest_Testcase and have all helper methods you need. All tests wich need them will extend this class.

Second issue is autoloading. When tests run by kohana test runner, or directly by phpunit ,which use phpunit.xml config file. Only Kohana::auto_load() avaliable for both variants. And additional Kohana_Unittest_Tests::autoload() when test runs with kohana phpunit module . Both of this autoloaders will fail to load your basic classes which use namespaces. To resolve this you can do require_once inside each file to include needed classes (wich looks bad idea). Or rewrite tests using kohana naming conventions without namespaces so default autoloader will work.

The classes I18n\Testcase and I18n\Plural\Testcase in fact are abstract base classes. My previous experiments with testing using standard Kohana bootstrap showed these classes were not loaded, even under the naming convention, as long as they were under 'tests' folder. And there's also helpers.php, which contains some stub classes used by tests, which I could've put in the separate files, but what the heck if they didn't autoload anyway.

To rewrite these classes using the naming convention would require to put them outside of the 'tests' folder (at least it was before, haven't checked with KO3.3), which is unacceptable.

I'm going to look into Kohana_Unittest_Tests::autoload() to see if there's a solution.

As for the test runner: AFAIK, phpunit follows certain rules when looking for test files in order to not include all files. I'd see it more as Kohana issue if it doesn't do the same.

http://www.phpunit.de/manual/3.7/en/organizing-tests.html
Php unit can run each test after scanning test folder, or use phpunit.xml.
First variant works absolutely like kohana test runner.
Second variant is custom way. And both require correct autoloader or using autoloaders loaded in bootstrap file.
Kohanas default autoloader will not work for tests:

public static function auto_load($class, $directory = 'classes'){}

Seems it will look for class only in classes folder by default

/**
     * Loads test files if they cannot be found by kohana
     * @param <type> $class
     */
    static function autoload($class)
    {
        $file = str_replace('_', '/', $class);

        if ($file = Kohana::find_file('tests', $file))
        {
            require_once $file;
        }
    }

Kohana_Unittest_Tests::autoload() in kohana test runner will look for class starting from tests folder.
For now this autoloader not support namespaces for tests. We can post feature request for this to kohana team.
But now to make module tests work seamless with kohana it require to not use namespaces for test classes.
And put all tests directly to test folder not tests/I18n. I try to do this locally and all work perfect.

About helpers, seems Tests\Generator not used inside tests.
Tests\Rules can be moved to bottom of CoreTests file where it used. Kohana team do same way in their tests.
Tests\Reader used in few tests so it can be moved to tests/Reader.php

What you think about this?

That's exactly what I've had in mind:

Note

If you point the PHPUnit command-line test runner to a directory it will look for *Test.php files.

It's really daring to assume no other files will ever be in the tests folder.

I agree that the all the classes should be organized the same way. The organization of the test classes repeat the module classes organization, and I feel this is correct. I just need to break down helpers.php to follow he same principle, too. I really don't think it's a good idea to give up any class organization in order to conform to a specific autoloader and/or test runner.

But I still require a custom bootstrap for when I need to test the project without the rest of Kohana, and, as you've mentioned, there are some other remaining files that cause problems with the Kohana test runner.

What can be done now:

  • As an intermediate solution, I'd recommend to disable/remove/blacklist this module's tests for now. You really aren't required to test any 3rd party code, if only from the curiosity.
  • A pull request(s) should be made for the Kohana Unittest module to add the same level of support to autoloader as Kohana Core autoloader has, and for the test runner to skip files other than *Test.php (I haven't checked this one myself). Another nice addition would be that the Unittest module would include a "custom bootstrap" for the modules, in a similar way like Kohana Core does with the init.php files (if the feature is not there already, I haven't looked into the Unittest module very closely).

I think it should resolve these problems.