Magento 2 Integration Tests: @magentoConfigFixture

I did not find a good documentation on how to use the @magentoConfigFixture annotation for configuration fixtures in Magento 2 integration tests, so here is my summary after inspecting the core code (Magento 2.1.0, Magento\TestFramework\Annotation\ConfigFixture)

How to use @magentoConfigFixture

Set default value 42 for configuration path x/y/z:

/**
 * @magentoConfigFixture default/x/y/z 42
 */

Set store specific value 42 for configuration path x/y/z in store with code store1

/**
 * @magentoConfigFixture store1_store x/y/z 42
 */

Set store specific value 42 for configuration path x/y/z in current store (i.e. default store)

/**
 * @magentoConfigFixture current_store x/y/z 42
 */

These are all possible formats. The first parameter must end with _store or be ommitted. And if it is omitted, the path must start with default/, otherwise it is ignored.

Implications

  • You cannot set configuration values on website level
  • Do not use “current” as a real store code, otherwise you cannot use config fixtures for that store

EcomDev PHPUnit Tip #14

For years, the test framework EcomDev_PHPUnit is quasi-standard for Magento unit tests. The current version is 0.3.7 and last state of official documentation is version 0.2.0 – since then, much has changed which you have to search yourself in code and GitHub issues. This series shall collect practical usage tips.

Tip #14: Registry Fixtures

As already explained in Tip #1, helpers, singletons and registry values can be reset per test. Finding the problematic singletons etc. often was the most difficult part of writing integration tests with EcomDev, so I started to collect them centralized in one fixtures/registry.yaml file for all tests 1. Better reset one too many than one to little.

The file is structured like this:
Continue reading “EcomDev PHPUnit Tip #14”

The week weeks on StackExchange #24-29 / 2016

The weekly format did not last long, but a few posts on Magento StackExchange assembled in the last 5 weeks that might be worth some attention (and a new t-shirt):

Magento 2

Magento 1

The week on StackExchange #9 / 2016

I’ll try a new weekly format on the blog with a summary of recent questions and answers from StackExchange, all around PHP and Magento. Let’s see how it works out and start right away:

New Answers

Open questions

In the next week there is more to come on the topic of Magento 2, since I am just starting to get deeper into it.

EcomDev_PHPUnit Tip #9

For years, the test framework EcomDev_PHPUnit is quasi-standard for Magento unit tests. The current version is 0.3.7 and last state of official documentation is version 0.2.0 – since then, much has changed which you have to search yourself in code and GitHub issues. This series shall collect practical usage tips.

Tip #9: Checkout Test

3 Years ago I already wrote an article about how to write a checkout integration test. But the practices used there are not longer up to date and some workarounds have become unnecessary. This post shows what’s necessary to write a test that simulates the Magento checkout, using techniques learned in Tip #1.

  1. Since there are some singletons involved, make sure to reset their state:
    /*
     * @test
     * @singleton checkout/session
     * @singleton customer/session
     * @singleton checkout/cart
     */
    
  2. You should visit the cart page once to trigger totals collection. Assuming, the customer id is 1 and she has an active quote (from previously added products in the test or from a quote fixture), you start with:
    $this->customerSession(1);
    $this->dispatch('checkout/cart');
    
  3. Before each new request, you have to reset the checkout session singleton manually within the test, otherwise the quote is not reloaded and you might even lose it completely:
    Mage::unregister('_singleton/checkout/session');
    $this->customerSession(1);
    $this->dispatch('checkout/onepage');
  4. Sometimes you want to logout a customer with active shopping cart. This needs three steps:
    Mage::getSingleton('customer/session')->logout();
    Mage::getSingleton('checkout/cart')->unsetData();
    $this->guestSession();

Mock Admin Session With EcomDev_PHPUnit In Magento Enterprise

In integration tests with EcomDev_PHPUnit_Test_Case_Controller there is a useful helper method adminSession(), to test requests in the Magento backend. With Magento Enterprise you might get this error message if you use it:

Exception: Warning: in_array() expects parameter 2 to be array, null given in /home/vagrant/mwdental/www/app/code/core/Enterprise/AdminGws/Model/Role.php on line 83

As seen on Magento EE 1.14.1.

Without disclosing details about the Enterprise modules, here a solution where the responsible observer gets mocked:

$adminObserverMock = $this->getModelMock(
    'enterprise_admingws/observer',
    array('adminControllerPredispatch'));
$adminObserverMock->expects($this->any())
    ->method('adminControllerPredispatch')
    ->will($this->returnSelf());
$this->replaceByMock('singleton', 'enterprise_admingws/observer',
    $adminObserverMock);
$this->adminSession();