Giter Site home page Giter Site logo

ecomdev / ecomdev_phpunit Goto Github PK

View Code? Open in Web Editor NEW
300.0 38.0 165.0 750 KB

Magento PHPUnit Integration

Home Page: http://www.ecomdev.org/shop/code-testing/php-unit-test-suite.html

License: Open Software License 3.0

PHP 100.00%
magento phpunit

ecomdev_phpunit's Introduction

EcomDev

Magento PHPUnit Integration

Magento is a quite complex platform without built in unit test suite, so the code is not oriented on running tests over it.

This extension was created especially for resolving this problem and promoting test driven development practices in Magento developers community. It doesn't change core files or brake your Magento instalment database, because all the system objects are replaced during the run-time with the test ones and a separate database connection is used for tests.

System Requirements

  • PHP 5.3 or higher
  • PHPUnit 3.7.x
  • Magento CE1.4.x-1.7.x/PE1.9.x-PE1.10.x/EE1.9.x-1.12.x

Build Status

  • Latest Release: Master Branch
  • Development Branch: Development Branch

Documentation

Also you may follow our related blogposts.

Installation

  1. There are two ways of obtaining the extension:

    modman clone git://github.com/EcomDev/EcomDev_PHPUnit.git 
    • Add extension as dependency in your composer.json to install it from Magento Composer Repository
      {
            "require": {
               "ecomdev/ecomdev_phpunit": "*"
            }
      }
  2. Open your terminal and navigate to your magento directory for performing the following command, they are required to configure system for running the test suite

    # Shell scripts needs to be run from this directory
    cd $YOUR_MAGENTO_DIRECTORY/shell 
    # Specify your test database name and base url for controller tests
    php ecomdev-phpunit.php -a magento-config --db-name $DB_NAME --base-url http://your.magento.url/

    If you receive a warning on PHPUnit checks for optional packages, run the following command

    php ecomdev-phpunit.php -a fix-autoloader
  3. Run the unit tests first time for installing test database. It will take about 3 minutes.

     $ phpunit 
    
  4. If it shows that there was no tests found, it means that extension was successfully installed. If it shows some errors, then it means, that your customizations has install scripts that relay on your current database data and you should fix them. Or use your dev database as a base for the tests, but prior first time running the suite.

Issue Tracker

We use github issue tracker only for contributions management. If you want to post an issue please use our Issue Tracker

Contributions

If you want to take a part in improving our extension please create branches based on dev one.

###Create your contribution branch:

$ git checkout -b [your-name]/[feature] dev

Then submit them for pull request.

ecomdev_phpunit's People

Contributors

alexandrkorolev avatar aligentjim avatar bogdanmuresan avatar chernjie avatar cmuench avatar colinmollenhour avatar fabianaromagnoli avatar flyingmana avatar fooman avatar ivanchepurnyi avatar johnholden avatar jonpday avatar jzahedieh avatar quafzi avatar schrank avatar screamingdev avatar vinai avatar vsushkov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ecomdev_phpunit's Issues

Zend_Log_Formatter_Simple not being loaded

Test running is working fine for passing tests, but if a test fails I am receiving this error, instead of the PHPUnit or exception output (in the case of fatals)

PHP Fatal error: spl_autoload(): Class Zend_Log_Formatter_Simple could not be loaded in [redacted]/app/Mage.php on line 748
PHP Stack trace:
PHP 1. {main}() /usr/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP 3. PHPUnit_TextUI_Command->run() /usr/share/php/PHPUnit/TextUI/Command.php:130
PHP 4. mageCoreErrorHandler() [redacted]/app/code/core/Mage/Core/functions.php:0
PHP 5. Mage::log() [redacted]/app/code/core/Mage/Core/functions.php:247

The tests actually pass fine on my local machine, but are failing on my test rig.

Test rig is running:
PHP 5.3.2 on Ubuntu 10.04.4
PHPUnit 3.6.10
EcomDev_PhpUnit - Latest git master

I am happy to provide further environment information if required.

Thank you.

Adminhtml controller dispatch issue

Hello

I'm trying to test my adminhtml controllers, each test works fine in isolation, but as soon as I have 2 test cases that dispatch a request, I get a fatal error.

I've created a gist with the relevant classes https://gist.github.com/2006542
The abstract.php is just to create a fake admin user and set the session.

It looks to me like the layout is not being cleared, so when dispatch is called twice the functions / classes involved in rendering it have already been included and declared.

This doesn't occur when testing frontend controllers.

I'm using the master branch, I haven't tried this on dev as I haven't had much luck getting it to work on my test box.

Stack Trace

Fatal error: Cannot redeclare drawMenuLevel() (previously declared in [redacted]\magento\app\design\adminhtml\default\default\template\page\menu.phtml:33) in [redacted]\magento\app\design\adminhtml\default\default\template\page\menu.phtml on line 43

Call Stack:
    0.0004     327888   1. {main}() [redacted]\php\phpunit:0
    0.0195     764928   2. PHPUnit_TextUI_Command::main() [redacted]\php\phpunit:44
    0.0195     765280   3. PHPUnit_TextUI_Command->run() [redacted]\php\PEAR\PHPUnit\TextUI\Command.php:125
    0.4717   13550840   4. PHPUnit_TextUI_TestRunner->doRun() [redacted]\php\PEAR\PHPUnit\TextUI\Command.php:187
   20.3997   15425856   5. PHPUnit_Framework_TestSuite->run() [redacted]\php\PEAR\PHPUnit\TextUI\TestRunner.php:325
   20.3998   15427864   6. PHPUnit_Framework_TestSuite->run() [redacted]\php\PEAR\PHPUnit\Framework\TestSuite.php:705
   29.6948   35766328   7. PHPUnit_Framework_TestSuite->run() [redacted]\php\PEAR\PHPUnit\Framework\TestSuite.php:705
   29.6952   35766568   8. PHPUnit_Framework_TestSuite->runTest() [redacted]\php\PEAR\PHPUnit\Framework\TestSuite.php:745
   29.6952   35766568   9. PHPUnit_Framework_TestCase->run() [redacted]\php\PEAR\PHPUnit\Framework\TestSuite.php:772
   29.6953   35766568  10. PHPUnit_Framework_TestResult->run() [redacted]\php\PEAR\PHPUnit\Framework\TestCase.php:748
   29.6984   35769360  11. PHPUnit_Framework_TestCase->runBare() [redacted]\php\PEAR\PHPUnit\Framework\TestResult.php:649
   29.8478   36000912  12. PHPUnit_Framework_TestCase->runTest() [redacted]\php\PEAR\PHPUnit\Framework\TestCase.php:801
   29.8479   36001800  13. ReflectionMethod->invokeArgs() [redacted]\php\PEAR\PHPUnit\Framework\TestCase.php:939
   29.8479   36001816  14. Skywire_PressRelease_Test_Controller_Adminhtml_IndexAction->testIndexAction() [redacted]\php\PEAR\PHPUnit\Framework\TestCase.php:939
   29.8479   36001888  15. EcomDev_PHPUnit_Test_Case_Controller->dispatch() [redacted]\magento\app\code\local\Skywire\PressRelease\Test\Controller\Adminhtml\IndexAction.php:36
   29.8683   36032752  16. Mage_Core_Controller_Varien_Front->dispatch() [redacted]\magento\app\code\community\EcomDev\PHPUnit\Test\Case\Controller.php:1978
   29.8769   36032816  17. Mage_Core_Controller_Varien_Router_Standard->match() [redacted]\magento\app\code\core\Mage\Core\Controller\Varien\Front.php:176
   29.8805   36033328  18. Mage_Core_Controller_Varien_Action->dispatch() [redacted]\magento\app\code\core\Mage\Core\Controller\Varien\Router\Standard.php:250
   29.9068   36034296  19. Skywire_PressRelease_Adminhtml_IndexController->indexAction() [redacted]\magento\app\code\core\Mage\Core\Controller\Varien\Action.php:420
   30.0618   36193448  20. Mage_Core_Controller_Varien_Action->renderLayout() [redacted]\magento\app\code\local\Skywire\PressRelease\controllers\Adminhtml\IndexController.php:35
   30.0636   36194152  21. EcomDev_PHPUnit_Model_Layout->getOutput() [redacted]\magento\app\code\core\Mage\Core\Controller\Varien\Action.php:391
   30.0637   36194672  22. Mage_Core_Model_Layout->getOutput() [redacted]\magento\app\code\community\EcomDev\PHPUnit\Model\Layout.php:492
   30.0637   36194720  23. Mage_Core_Block_Abstract->toHtml() [redacted]\magento\app\code\core\Mage\Core\Model\Layout.php:529
   30.0650   36195152  24. Mage_Adminhtml_Block_Template->_toHtml() [redacted]\magento\app\code\core\Mage\Core\Block\Abstract.php:863
   30.0653   36195360  25. Mage_Core_Block_Template->_toHtml() [redacted]\magento\app\code\core\Mage\Adminhtml\Block\Template.php:81
   30.0654   36195360  26. Mage_Core_Block_Template->renderView() [redacted]\magento\app\code\core\Mage\Core\Block\Template.php:286
   30.0707   36195448  27. Mage_Core_Block_Template->fetchView() [redacted]\magento\app\code\core\Mage\Core\Block\Template.php:272
   30.0723   36264480  28. include('[redacted]\magento\app\design\adminhtml\default\default\template\page.phtml') [redacted]\magento\app\code\core\Mage\Core\Block\Template.php:241
   30.3002   36262896  29. Mage_Core_Block_Abstract->getChildHtml() [redacted]\magento\app\design\adminhtml\default\default\template\page.phtml:53
   30.3002   36262960  30. Mage_Core_Block_Abstract->_getChildHtml() [redacted]\magento\app\code\core\Mage\Core\Block\Abstract.php:526
   30.3003   36262960  31. Mage_Core_Block_Abstract->toHtml() [redacted]\magento\app\code\core\Mage\Core\Block\Abstract.php:582
   30.3016   36263104  32. Mage_Adminhtml_Block_Template->_toHtml() [redacted]\magento\app\code\core\Mage\Core\Block\Abstract.php:863
   30.3019   36263104  33. Mage_Core_Block_Template->_toHtml() [redacted]\magento\app\code\core\Mage\Adminhtml\Block\Template.php:81
   30.3019   36263104  34. Mage_Core_Block_Template->renderView() [redacted]\magento\app\code\core\Mage\Core\Block\Template.php:286
   30.3064   36263200  35. Mage_Core_Block_Template->fetchView() [redacted]\magento\app\code\core\Mage\Core\Block\Template.php:272

iew() [redacted]\magento\app\code\core\Mage\Core\Block\Template.php:286
PHP  35. Mage_Core_Block_Template->fetchView() [redacted]\magento\app\code\core\Mage\Core\Block\Template.php:272

Host is not set for base url

My Error

I'm receiving the following error upon running phpunit in my magento root directory.

PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'Cannot run controller test, because the host is not set for base url.' in /var/www/mysite/magento/mage_extensions/EcomDev/PHPUnit/app/code/community/EcomDev/PHPUnit/Controller/Request/Http.php:355
Stack trace:
#0 /var/www/mysite/magento/app/code/core/Mage/Core/Model/Cookie.php(105): EcomDev_PHPUnit_Controller_Request_Http->getHttpHost()
#1 /var/www/mysite/magento/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php(97): Mage_Core_Model_Cookie->getDomain()
#2 /var/www/mysite/magento/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php(158): Mage_Core_Model_Session_Abstract_Varien->start(NULL)
#3 /var/www/mysite/magento/app/code/core/Mage/Core/Model/Session/Abstract.php(84): Mage_Core_Model_Session_Abstract_Varien->init('commercebug', NULL)
#4 /var/www/mysite/magento/mage_extensions/DeptpurchasingmysitemerceBug/Model/Session.php(6): Mage_Core_Model_Sessi in /var/www/mysite/magento/mage_extensions/EcomDev/PHPUnit/app/code/community/EcomDev/PHPUnit/Controller/Request/Http.php on line 355

My local.xml.phpunit settings

The following is the default portion of my local.xml.phpunit file:

<default>
    <web>
        <seo>
            <use_rewrites>1</use_rewrites>
        </seo>
        <secure>
            <base_url>http://localstaging.mysite.com/</base_url>
        </secure>
        <unsecure>
            <base_url>http://localstaging.mysite.com/</base_url>
        </unsecure>
        <url>
            <redirect_to_base>0</redirect_to_base>
        </url>
    </web>
</default>

What I've Done

To see if I had a caching issue, I've cleared the cache, removed the entire database and started from scratch by running phpunit again from the root directory.

Question

What am I missing that is causing this error? Can you point me in the right direction?

Mage::getStoreConfig

Looks like this method will never return any valid value "Mage::getStoreConfig()" - it always returns string(0) ""

Config fixtures not working in Magento 1.11.2.0

I can't get config fixtures working in the latest Magento Enterprise Edition.

Simplified example of what i try to achive. (Test if a certain value is set in the config)

// Test Class
class Foo_Bar_Test_Helper_Config
    extends EcomDev_PHPUnit_Test_Case
{
    /**
     * @loadFixture config
     * @dataProvider dataProvider
     * 
     * @param string $dataSet
     * @param string $data configPath
     */
    public function testConfigValues($dataSet, $data)
    {
        $result = Mage::getStoreConfig($data);

        $this->assertEquals(
            $this->expected('%s', $dataSet)->getResult(),
            $result
        );
    }
}
# dataProvider
-
  - 1-1
  - "payment_ccsave_title"
# expectations
1-1:
  result: "Pay with credit card"
# fixtures
config:
  payment_ccsave_title: "Pay with credit card"

If i dump the value using Mage::getStoreConfig i always receive NULL as a value.

The "core_config_data" table is empty except for one entry
1 default 0 catalog/category/root_id 2
i expected to find all values from the live database here.

I have tried the latest two tags of your extension as well as the current dev branch.
Magento is running 1.11.2.0 EE
phpunit 3.6.5

Undefined index: _store

Exception: Notice: Undefined index: _store in app/code/community/EcomDev/PHPUnit/Test/Case/Controller.php on line 872

loading Fxitures and Fatal runtime errors

Every time when execution of tests is stopped by "Fatal Error" or "die()" call - we get the problem with fixtures. So the data which is saved into DB like $scopeModel in EcomDev_PHPUnit_Model_Fixture on line 829 cannot be written again since discard() method wasnt called and all the data which was saved into DB during the initial execution is still there - so would it be reasonable to add some routine for checking data for existence ?
Something like the following:
$scopeModel = Mage::getModel(self::$_scopeModelByType[$type]);
$scopeModel->load($row['website_id'])->delete();

Its really annoying when after another Fatal Error you have to reinstall the DB completely.

websites, store groups, stores break after first use

My test database, which was copied over from development, was setup with multiple stores and websites - this worked fine on all my tests, none of which had a multiple store configuration in their fixture file, until I tried to write a new test that included a new configuration because I was specifically testing it. Now when I run my tests I'm getting a SQL error on this specific test.

Zend_Db_Statement_Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'base' for key 'UNQ_MAG_CORE_WEBSITE_CODE'

This is what my initial DB looked like for websites

mysql> select * from mag_core_website;
+------------+-------+--------------+------------+------------------+------------+
| website_id | code  | name         | sort_order | default_group_id | is_default |
+------------+-------+--------------+------------+------------------+------------+
|          0 | admin | Admin        |          0 |                0 |          0 |
|          1 | base  | Main Website |          0 |                1 |          1 |
+------------+-------+--------------+------------+------------------+------------+

and this was the part of the fixture file that is throwing the error:

scope:
    website: # Initializes websites
        - website_id: 1
          code: "base"
          name: "Main Website"
          default_group_id: 1

It appears I can make this work if I remove website_id: 1 from my test database and have the tests create/remove the entry, but then all my other tests start to break. The only way I see to fix that then will be to add the same multi store markup to all my fixture config files....which I have a lot and ideally don't want to do.

Is there a better way to handle this? I could always use different ID's but if we ever need to adjust these in the DB for some reason and it creates a conflict again - then we'll have the same issue.

I'm concerned I'm going to have the same results when I add groups and/or stores to the fixture as well...although I haven't gotten that far yet.

PHP Warnings and overwriting

Hi, Ivan.

I always get this errors when running tests:

2012-06-17T15:33:54+00:00 ERR (3): Warning: include(File.php): failed to open stream: No such file or directory  in D:\wamp\www\mage-test\lib\Varien\Autoload.php on line 93
2012-06-17T15:33:54+00:00 ERR (3): Warning: include(File.php): failed to open stream: No such file or directory  in D:\wamp\www\mage-test\lib\Varien\Autoload.php on line 93
2012-06-17T15:33:54+00:00 ERR (3): Warning: include(): Failed opening 'File.php' for inclusion (include_path='D:\wamp\www\mage-test\app\code\local;D:\wamp\www\mage-test\app\code\community;D:\wamp\www\mage-test\app\code\core;D:\wamp\www\mage-test\lib;.;D:\wamp\bin\php\php5.3.10\pear')  in D:\wamp\www\mage-test\lib\Varien\Autoload.php on line 93

I've traced it down to
https://github.com/IvanChepurnyi/EcomDev_PHPUnit/blob/master/app/code/community/EcomDev/PHPUnit/Model/Config.php#L238

I've changed

$this->setNode('global/cache/backend', 'file');

to

$this->setNode('global/cache/backend', 'File');

... and it shows no more.

I don't know exactly which version I'm using, but I'm certain it's not the latest one. But that's irrelevant, because that line looks the same.


Now on to the next errors. These are also present with the above ones.

2012-06-17T15:07:21+00:00 ERR (3): Recoverable Error: Argument 1 passed to Mage_Core_Model_Store::setWebsite() must be an instance of Mage_Core_Model_Website, null given, called in D:\wamp\www\mage-test\app\code\core\Mage\Core\Model\App.php on line 624 and defined  in D:\wamp\www\mage-test\app\code\core\Mage\Core\Model\Store.php on line 304
2012-06-17T15:07:21+00:00 ERR (3): Recoverable Error: Argument 1 passed to Mage_Core_Model_Store_Group::setWebsite() must be an instance of Mage_Core_Model_Website, null given, called in D:\wamp\www\mage-test\app\code\core\Mage\Core\Model\App.php on line 644 and defined  in D:\wamp\www\mage-test\app\code\core\Mage\Core\Model\Store\Group.php on line 235

I didn't get the chance to look at this, though.

Anyway, my main concern here is the ability to overwrite your classes to be able to fix things, including EcomDev_PHPUnit_Model_App, but I don't know how exactly, as the declaration resides in a custom xml configuration. I'm asking about overwriting because I'm not always able to update the module to the latest version. Maybe this is not the place to answer such questions, but perhaps you could have a look at the errors above, especially the first one.

Move all assertions to a helper classes

Move all custom assert* methods into helper classes with easy access via some helper.

The methods inclusion into existing classes can be done by defining __callStatic and invoking some static class from extension.

assertRedirectToUrlRegExp does not work?

I have an assertion

        $this->assertRedirectToUrlRegExp('#.*/wishlist/index/index/.*#');

This fails:

Failed asserting that request header "Location" value matches PCRE pattern "#.*/wishlist/index/index/.*#".
http://foobar.local/wishlist/index/index/wishlist_id/7/

When I debug into it, I see that \PHPUnit_Framework_Constraint_PCREMatch::matches returns true.

Also in \PHPUnit_Framework_Constraint::evaluate $success is TRUE, BUT: $returnResult is FALSE and so the result is not passed up.

The call to callProtectedByType does not specify the parameter
https://github.com/IvanChepurnyi/EcomDev_PHPUnit/blob/master/lib/EcomDev/PHPUnit/Constraint/Abstract.php#L169

So I think there might be a problem?

Moving test config to a separate configuration file.

All about the module seems promising, I am only concerned about having extra XML in config.xml that does not do anything in production environment.
It would be nice to have the option to put test configuration in a dedicated file, such as test.xml for example.
This will give better maintainability of the code and an option to easily exclude test code from distributed code. Not that it is bad to have test files along with module's files but for most users they will cause confusion and more than that, test files are not useful unless EcomDev_PHPUnit is also installed.

Error with fresh install

I tried doing a fresh install with modman, I'm getting the following error

PHPUnit 3.7.22 by Sebastian Bergmann.

Configuration read from /srv/share/magento_1.7.2.0/phpunit.xml.dist

FFFFF

Time: 1 second, Memory: 19.50Mb

There were 5 failures:

  1. Warning
    PHP Fatal error: Uncaught exception 'Exception' with message 'Warning: include(PHPUnit/Extensions/Story/TestCase.php): failed to open stream: No such file or directory in /srv/share/magento_1.7.2.0/lib/Varien/Autoload.php on line 93' in /srv/share/magento_1.7.2.0/app/code/core/Mage/Core/functions.php:245
    Stack trace:
    #0 /srv/share/magento_1.7.2.0/lib/Varien/Autoload.php(93): mageCoreErrorHandler(2, 'include(PHPUnit...', '/srv/share/mage...', 93, Array)
    #1 /srv/share/magento_1.7.2.0/lib/Varien/Autoload.php(93): Varien_Autoload::autoload()
    #2 [internal function]: Varien_Autoload->autoload('PHPUnit_Extensi...')
    #3 [internal function]: spl_autoload_call('PHPUnit_Extensi...')
    #4 phar:///usr/local/bin/phpunit/PHPUnit/Util/GlobalState.php(409): class_exists('PHPUnit_Extensi...')
    #5 phar:///usr/local/bin/phpunit/PHPUnit/Util/GlobalState.php(395): PHPUnit_Util_GlobalState::addDirectoryContainingClassToPHPUnitFilesList('PHPUnit_Extensi...', 2)
    #6 phar:///usr/local/bin/phpunit/PHPUnit/Util/Filter.php(76): PHPUnit_Util_GlobalState::phpu in /srv/share/magento_1.7.2.0/app/code/core/Mage/Core/functions.php on line 245

EcomDev breaks when adding an test class without tests inside

When creating a new testclass without any test methods inside, EcomDev adds an Error Class "PHPUnit_Framework_Warning" with message "No tests found in class '...' to the tests array.
EcomDev then tries to execute the "Warning" test.

I'm not sure if EcomDev is responsible for collecting the tests or if PHPUnit does this.

Wrong Modulename detection in \EcomDev_PHPUnit_Model_App::getModuleNameByClassName

Modulename detection is not working correctly when Modules like these exists:

N98_Catalog
N98_CatalogGrouped

        foreach ($this->getConfig()->getNode('modules')->children() as $module) {
            if (strpos($className, $module->getName()) === 0) {
               $moduleName = $module->getName();
               break;
            }
        }

By using strpos, the function will always return N98_Catalog.

Should singletons be cleaned after each test?

SCENARIO 1

Changing singleton state will be visible in another test case

Test_Model_A
/**
 * @test
 */
public function first()
{
    Mage::getSingleton('checkout/cart')->setId(999);
    $this->assertEquals(999, Mage::getSingleton('checkout/cart')->getId());
}

/**
 * @test
 */
public function second()
{
    $this->assertEquals(null, Mage::getSingleton('checkout/cart')->getId());
}
Test_Model_B
/**
 * @test
 */
public function third()
{
    $this->assertEquals(null, Mage::getSingleton('checkout/cart')->getId());
}

output

There were 2 failures:

1) Test_Model_A::second
Failed asserting that 999 matches expected null.

2) Test_Model_B::third
Failed asserting that 999 matches expected null.

SCENARIO 2

What if some method of controller/block/model modify a singleton? We cannot predict what was changed in system.

Module_Model_Example

public function changeSingleton()
{
    Mage::getSingleton('checkout/cart')->setId(1);
    return 'haba';
}
Test_Model_A
/**
 * @test
 */
public function first()
{
     Mage::getSingleton('checkout/cart')->setId(999);
     $this->assertEquals(999, Mage::getSingleton('checkout/cart')->getId());
     $this->assertEquals('haba', Mage::getModel('example')->changeSingleton());
}

/**
 * @test
 */
public function second()
{
    $this->assertEquals(999, Mage::getSingleton('checkout/cart')->getId());
}

output

There was 1 failure:

1) Test_Model_A::second
Failed asserting that 1 matches expected 999.

Support annotations per test function/class to enable/disable cache

For testing certain functionalities it is useful to be able to turn off (or on) caching.
I would suggest something like:

/**
 * @cache on|off all|type ...
 */
class MyCompany_MyModule_Test_Class extends EcomDev_PHPUnit_Test_Case
{
    /**
     * @test
     * @cache on|off all|type ...
     */
    public function doTest() {
        // ...
    }
}

controller tests do not load custom layout template

I've written a controller test and am asserting that what's in my .phtml comes out in the test.

When I go to the page in the browser, the .phtml content is there.

When I assert for it in the test case, it's not.

The controller action is simply load/render.

The phtml is simply a php file printing one line.

The test is:

public function testDispatch()
{
    $this->dispatch('credex/standard/redirect');

    $this->assertRequestRoute('credex/standard/redirect');

    $this->assertLayoutBlockCreated('left');
    $this->assertLayoutBlockCreated('right');
    $this->assertLayoutBlockRendered('content');
    $this->assertLayoutBlockTypeOf('left', 'core/text_list');
    $this->assertLayoutBlockNotTypeOf('left', 'core/links');

    // FIXME: this doesn't work, so for now I work around it
    //$this->assertResponseBodyContains('Magento');
    $this->_assertResponseBodyContains('Magento');
    // FIXME: in a test, my template does not get invoked
    $this->_assertResponseBodyContains('Welcome to your custom module');

    return $this;
}

(I use a custom assertResponseBodyContains because I found the standard one did not work - are there any unit tests out there in a git repo that use it that I can check ?)

public function _assertResponseBodyContains($string)
{
$body = $this->getResponse()->getOutputBody();
$constraint = $this->stringContains($string);
$this->assertThat($body, $constraint);
}

Are there any known and working tests of controllers out there ? Preferably one with a custom layout template ?

Test Helpers

Implement test helpers to make easy use of Magento API in the tests.

Should automatically replace session singleton and disable class constructor in mock

$this->mockSession('customer/session'); 

Emulate logged in customer session

$this->customerSession($customerId);

Emulate admin panel session

// Full rights admin
$this->adminSession();
// Limited rights admin
$this->adminSession(array('acl/resource/name'));
// Use non-faked admin user
$this->adminSessionByUser($adminUserIdOrUsername);

Etc

Experimental branch:
https://github.com/IvanChepurnyi/EcomDev_PHPUnit/tree/feature/test-helpers

Executing user defined group causes output as: 1 skipped

I tried define my own group by @gruop annotation. Executing this group causes a output as below:

OK, but incomplete or skipped tests! Tests: 0, Assertions: 0, Skipped: 1.

No matter if I have 10 or 1 test, if they will pass or not, I always get 1 skipped result.

Exclude directories in phpunit.xml.dist

How to configure the phpunit.xml.dist in order to exclude directories or groups like app/code/community

I have tried different configurations but nothing seems to has an effect.

Testing controller POST action

Like in title.

I'm trying:

$this->getRequest()->setMethod('POST');
$this->dispatch('customer/account/login');
$this->assertEquals('POST', $_SERVER['REQUEST_METHOD']); // ok

but phpunit ivokes loginAction instead loginPostAction

setCurrentStore not working when dispatch() a controllertest

$this->setCurrentStore('test_storeview');
$this->dispatch('/');

Will fall back to default storeview.

Problem is in \EcomDev_PHPUnit_Test_Case_Controller::getUrlModel when no _store param is given in arguments.

    if ($params['_store'] !== EcomDev_PHPUnit_Model_App::ADMIN_STORE_CODE) {
        $this->setCurrentStore($params['_store']);
        $urlModel = Mage::getModel('core/url');
    } else {
        ......
    }

There you should check if a store is already set by setCurrentStore() or don't call $this->setCurrentStore($params['_store']); if $params['_store'] is empty.

Caching Issues

I'm running into some caching issues. I haven't made any modifications to how caching is done. The extension has set the caching directory (phpunit.cache) and it isn't being populated, although if I run the same code outside of the Ecomdev_Phpunit extension it does properly populate and retrieve from the cache.

I've noticed that my test database has empty contents for the core_cache, core_cache_option, and core_cache_tag tables which seems like a red flag?

Thanks!

'key' column name getting interpreted at MySQL keyword KEY

I'm attempting to load data into the oauth_consumer table via a fixture (https://gist.github.com/jedgalbraith/5286238#file-fixture-yaml-L2).

I'm getting a MySQL syntax error due to the 'key' column in the 'ON DUPLICATE KEY UPDATE' portion of the query. The 'key' column is getting interpreted as the MySQL reserved keyword, 'KEY'. (https://gist.github.com/jedgalbraith/5286238#file-query-original-sql-L8)

If I manually add back ticks around key in the query and run it directly in MySQL, it runs correctly. (https://gist.github.com/jedgalbraith/5286238#file-query-edit-sql-L8)

Any ideas how to get back ticks around the key column name or otherwise get around this?

Is it possible to run the unit tests over the browser?

I'm still not too handy with running phpunit over the browser, I'm not sure if it may be supported out of the box and I just don't know how to get it to work. But if not, it would be great to have this support. Main reason being that if I need to debug a complex issue, I usually do that over the browser through my IDE.

I believe it's also possible to enable xdebug to work with phpunit over the command line, but have also run into issues getting that setup as well.

Latest version breaks some assertions functionnality

Hello,
In Magento Connect Version of your module (EcomDev_PHPUnit-0.2.0.1) some assertion doesn't work ie:
$this->assertModuleCodePool([whatever]); //always true
$this->assertModuleVersion([whatever]); //always true
but
$this->assertResponseBodyContains("Something"); // works as expected

In the Latest Version taken from GitHub (IvanChepurnyi-EcomDev_PHPUnit-15d232a) :
$this->assertModuleCodePool([whatever]); //works as expected
$this->assertModuleVersion([whatever]); //works as expected
but
$this->assertResponseBodyContains("Something"); // always fail

It seems to come from EcomDev_PHPUnit_Constraint_Abstract::evaluate wich was refactored.

Whe are using PHP 5.3.3-7 with PHPUnit 3.6.10.

Please provide a fix for this.

Thanks for your work.

Cannot delete cookies in controller test case

I am not sure if it is a bug. Here is a code:

public function testDeleteCookie()
{
    $session = Mage::getSingleton('customer/session');
    $session->getCookie()->delete($session->getSessionName());
}

exception:

Zend_Http_Exception: Cookies must have a domain

/var/www/magento-1.6.2-mrogacki/lib/Zend/Http/Cookie.php:124
/var/www/magento-1.6.2-mrogacki/lib/Zend/Http/Cookie.php:359
/var/www/magento-1.6.2-mrogacki/lib/Zend/Http/CookieJar.php:124
/var/www/magento-1.6.2-mrogacki/app/code/community/EcomDev/PHPUnit/Test/Case/Controller.php:1881
/var/www/magento-1.6.2-mrogacki/app/code/community/EcomDev/PHPUnit/Test/Case/Controller.php:1893
/var/www/magento-1.6.2-mrogacki/app/code/local/Tenmato/Jquery/Test/Block/Head.php:25

Why do I need this? Because customer/session has a logout() method which deletes cookies.

public function isLoggedOut()
{
    Mage::getSingleton('customer/session')->logout(); // exception
    $this->assertTrue(
        Mage::getSingleton('customer/session')->isLoggedIn(),
        "User was not logged out"
    );
}

In tearDown() everything works:

// its ok
protected function tearDown() {
    $session = Mage::getSingleton('customer/session');        
    $session->renewSession();
    $session->logout();
    parent::tearDown();
}
// its not ok
public function testDeleteCookie()
{
    $session = Mage::getSingleton('customer/session');
    $session->renewSession();
    $session->logout();
}

Issues in create test case for magento controller function

  1. PHP Fatal error: Call to undefined method Mage_Core_Controller_Request_Http:
    :reset() in C:\xampp\htdocs\Cacommons\app\code\community\EcomDev\PHPUnit\Test\Ca
    se\Controller.php on line 1905

Fatal error: Call to undefined method Mage_Core_Controller_Request_Http::reset()
in C:\xampp\htdocs\Cacommons\app\code\community\EcomDev\PHPUnit\Test\Case\Contr
oller.php on line 1905

  1. PHP Fatal error: Call to undefined method CA_Comparesort_Test_Controller_Index
    ::getMockBuilder() in C:\xampp\htdocs\Cacommons\app\code\community\EcomDev\PHPUn
    it\Test\Case.php on line 406

Fatal error: Call to undefined method CA_Comparesort_Test_Controller_Index::getM
ockBuilder() in C:\xampp\htdocs\Cacommons\app\code\community\EcomDev\PHPUnit\Tes
t\Case.php on line 406

Notice: Undefined offset: 2

Notice: Undefined offset: 2 in /lib/EcomDev/PHPUnit/Constraint/Controller/Request.php on line 86

The above happens when parsing route of type 'module/action'.
When route is exploded it has 2 fields, code on line 86 tries to pad the array, but uses array_pad in wrong way, it should be:

$routeParts = array_pad($routeParts, 3, null);

and not

array_pad($routeParts, 3-$routePartsCount, null);

PHP v.5.3.15
From manual:
array_pad() returns a copy of the input padded to size specified by pad_size with value pad_value.

Trouble with fixtures

So I'm trying to setup my fixture for my tests which work with the quote and quote_item objects.

The error I keep getting is:

EcomDev_PHPUnit_Model_Mysql4_Fixture_Exception: Unable to insert/update records for a table "sales/quote_item"

/srv/thirdparty/EcomDev_PHPUnit/app/code/community/EcomDev/PHPUnit/Model/Mysql4/Fixture.php:75
/srv/thirdparty/EcomDev_PHPUnit/app/code/community/EcomDev/PHPUnit/Model/Fixture.php:606
/srv/thirdparty/EcomDev_PHPUnit/app/code/community/EcomDev/PHPUnit/Model/Fixture.php:421
/srv/thirdparty/EcomDev_PHPUnit/app/code/community/EcomDev/PHPUnit/Test/Case.php:803
/srv/extensions/Bogo/development/app/code/local/Demac/Bogo/Test/Model/Observer.php:15

My fixture file looks like this:


tables:
  sales/quote:
    - entity_id: 1
      is_active: 1
      created_at: 2012-08-17 18:00:41
      updated_at: 2012-08-17 18:00:41
      converted_at: null
      is_virtual: 0
      is_multi_shipping: 0
      items_count: 1
      items_qty: 2.0000
      orig_order_id: 0
      store_to_base_rate: 1.0000
      store_to_quote_rate: 1.0000
      base_currency_code: CAD
      store_currency_code: CAD
      quote_currency_code: CAD
      grand_total: 26.0000
      base_grand_total: 26.0000
      checkout_method: null
      customer_id: null
      customer_tax_class_id: 3
      customer_group_id: 0
      customer_email: null
      customer_prefix: null
      customer_firstname: null
      customer_middlename: null
      customer_lastname: null
      customer_suffix: null
      customer_dob: null
      customer_note: null
      customer_note_notify: 1
      customer_is_guest: 0
      remote_ip: 192.168.0.1
      applied_rule_ids: 12
      reserved_order_id: null
      password_hash: null
      coupon_code: null
      global_currency_code: CAD
      base_to_global_rate: 1.0000
      base_to_quote_rate: 1.0000
      customer_taxvat: null
      customer_gender: null
      subtotal: 26.0000
      base_subtotal: 26.0000
      subtotal_with_discount: 26.0000
      base_subtotal_with_discount: 26.0000
      is_changed: 1
      trigger_recollect: 0
      ext_shipping_info: null
      gift_message_id: null
      is_persistent: 0
      customer_balance_amount_used: 0.0000
      base_customer_bal_amount_used: 0.0000
      use_customer_balance: null
      gift_cards: 'a:0:{}'
      gift_cards_amount: 0.0000
      base_gift_cards_amount: 0.0000
      gift_cards_amount_used: 0.0000
      base_gift_cards_amount_used: 0.0000
      gw_id: null
      gw_allow_gift_receipt: null
      gw_add_card: null
      gw_base_price: 0.0000
      gw_price: 0.0000
      gw_items_base_price: 0.0000
      gw_items_price: 0.0000
      gw_card_base_price: 0.0000
      gw_card_price: 0.0000
      gw_base_tax_amount: 0.0000
      gw_tax_amount: 0.0000
      gw_items_base_tax_amount: 0.0000
      gw_items_tax_amount: 0.0000
      gw_card_base_tax_amount: 0.0000
      gw_card_tax_amount: 0.0000
      use_reward_points: null
      reward_points_balance: 0
      base_reward_currency_amount: 0.0000
      reward_currency_amount: 0.0000
      base_customer_balance_amount_used: 0.0000
      gw_add_printed_card: null
      gw_printed_card_base_price: 0.0000
      gw_printed_card_price: 0.0000
      gw_printed_card_base_tax_amount: 0.0000
      gw_printed_card_tax_amount: 0.0000
      customer_is_loyalty_member: null
      customer_join_loyalty_on: null
    - entity_id: 2
    - entity_id: 3
  sales/quote_item:
    - item_id: 1
      quote_id: 1
      product_id: 1
      parent_item_id: null
      is_virtual: 0
      sku: 14156575-XS-9394
      name: LEGGING
      description: null
      applied_rule_ids: 0
      additional_data: null
      free_shipping: 0
      is_qty_decimal: 0
      no_discount: 0
      weight: 0.4000
      qty: 2
      price: 13.0000
      base_price: 13.0000
      custom_price: 10.0000
      discount_percent: 0.0000
      discount_amount: 0.0000
      base_discount_amount: 0.0000
      tax_percent: 0.0000
      tax_amount: 0.0000
      base_tax_amount: 0.0000
      row_total: 20.0000
      base_row_total: 20.0000
      row_total_with_discount: 0.0000
      row_weight: 0.0000
      product_type: configurable
      base_tax_before_discount: null
      tax_before_discount: null
      original_custom_price: 10.0000
      redirect_url: null
      base_cost: null
      price_incl_tax: 13.0000
      base_price_incl_tax: 13.0000
      row_total_incl_tax: 26.0000
      base_row_total_incl_tax: 26.0000
      hidden_tax_amount: null
      base_hidden_tax_amount: null
      gift_message_id: null
      weee_tax_disposition: 0.0000
      weee_tax_row_disposition: 0.0000
      base_weee_tax_disposition: 0.0000
      base_weee_tax_row_disposition: 0.0000
      weee_tax_applied: 'a:0:{}'
      weee_tax_applied_amount: 0.0000
      weee_tax_applied_row_amount: 0.0000
      base_weee_tax_applied_amount: 0.0000
      base_weee_tax_applied_row_amnt: null
      event_id: null
      giftregistry_item_id: null
      gw_id: null
      gw_base_price: null
      gw_price: null
      gw_base_tax_amount: null
      gw_tax_amount: null
  catalog/product:
    - product_id: 1

The only way that I made it run was by droping all the tables in the database(forcing to recreate everything from scratch) and running the test.

PDOException - Invalid catalog name: 1046 No database selected

I have created a test suite that I ran successfully for months. I changed my laptop, and in my new environment I'm not able to execute the tests, as it fails with the error message below:

'PDOException' with message 'SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected' in www/shop/lib/Zend/Db/Statement/Pdo.php:228

The database settings appear to be correct because when I first ran the test suite, it has successfully created the copy of the Magento database into the test database.

Error message and stack trace:

PHPUnit 3.6.12 by Sebastian Bergmann.

F
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected' in www/shop/lib/Zend/Db/Statement/Pdo.php:228
Stack trace:
#0 www/shop/lib/Zend/Db/Statement/Pdo.php(228): PDOStatement->execute(Array)
#1 www/shop/lib/Zend/Db/Statement.php(300): Zend_Db_Statement_Pdo->_execute(Array)
#2 www/shop/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)
#3 www/shop/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('SELECT `main_ta...', Array)
#4 www/shop/lib/Varien/Db/Adapter/Pdo/Mysql.php(337): Zend_Db_Adapter_Pdo_Abstract->query('SELECT `main_ta...', Array)
#5 www/shop/li in www/shop/lib/Zend/Db/Statement/Pdo.php on line 234

(note: I shrunk down full paths in the error messages)

It's definitely some local problem, however in it's current form it seems to be nearly impossible to fix, so I'd like to ask for some help on how to discover the root cause.

helperAdminSession() not working with Magento EE

helperAdminSession() is not working when using Magento EE.

An observer in Enterprise_AdminGws tries to set the Adminroles for the websites, but the Enterprise_AdminGws_Model_Role model is not filled with the correct values.

The error can be debugged in the following function:
\Enterprise_AdminGws_Model_Role::setAdminRole

Product fixtures could not be cleaned correctly

When I try to use catalog_product fixture, for some reason it could not clean in the end using truncate.
The error itself tells that it could not resolve the Foreign Key reference to cataloginventory_stock_item.
Magento EE1.12

We added manual delete for now. If you have not such problems, please post there for us to know that something wrong is with our configuration.

Thank you for such a great extension!
The dataProviders are awesome.

Custom write adapters for fixtures

One of my modules uses custom write adapters. The way that fixtures work they don't seem to be able to grab the write adapter for my tables, so I had to put in a bit of a hack in the fixtures model to support this.

Wrong Modulename detection in \EcomDev_PHPUnit_Model_App::getModuleNameByClassName

Modulename detection is not working correctly when Modules like these exists:

N98_Catalog
N98_CatalogGrouped

        foreach ($this->getConfig()->getNode('modules')->children() as $module) {
            if (strpos($className, $module->getName()) === 0) {
               $moduleName = $module->getName();
               break;
            }
        }

By using strpos, the function will always return N98_Catalog.

Multiple dispatches in one test run: Events not properly isloated

I have a module that registers a frontend event "controller_action_predispatch_wishlist_index_send"

Steps to reproduce:

  1. $this->dispatch('/);
  2. $this->dispatch('wishlist/index/send');
  3. Event controller_action_predispatch_wishlist_index_send is not fired

If I directly dispatch the "right" action, i.e. the action that fires the event, it will be fired:

Steps to reproduce:

  1. $this->dispatch('wishlist/index/send');
  2. Event controller_action_predispatch_wishlist_index_send is fired

I debugged this a little and there seems to be some kind of caching problem. After the first dispatch, the event cache is already initialized. Now during the second call, events that have not fired before, are just ignored.

Correction:

  • the two dispatches must be in seperate tests
  • there must be fixture loading involved, but the fixture can be empty
  • $this->assertEventDispatched('controller_action_predispatch_wishlist_index_send'); actually is not failing, but inside the dispatching the event is not really dispatched

I made a small test module to reproduce this: https://github.com/amenk/N98_EcomDevPHPUnitIssue

Running both tests

phpunit.phar --debug --filter N98_EcomDevPHPUnitIssue_Test_Controller_TestController
PHPUnit 3.7.13 by Sebastian Bergmann.

Configuration read from tests/integration/phpunit.xml

Starting test 'N98_EcomDevPHPUnitIssue_Test_Controller_TestController::aAction'.
.
Starting test 'N98_EcomDevPHPUnitIssue_Test_Controller_TestController::bAction'.
F

Time: 5 seconds, Memory: 55.50Mb

There was 1 failure:

  1. N98_EcomDevPHPUnitIssue_Test_Controller_TestController::bAction
    event was not really fired
    Failed asserting that null is true.

app/code/local/N98/EcomDevPHPUnitIssue/Test/Controller/TestController.php:30
phpunit.phar:524

FAILURES!
Tests: 2, Assertions: 4, Failures: 1.

Running only bAction

phpunit.phar --debug --filter N98_EcomDevPHPUnitIssue_Test_Controller_TestController::bAction
PHPUnit 3.7.13 by Sebastian Bergmann.

Configuration read from tests/integration/phpunit.xml

Starting test 'N98_EcomDevPHPUnitIssue_Test_Controller_TestController::bAction'.
.

Time: 4 seconds, Memory: 36.50Mb

OK (1 test, 4 assertions)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.