EcomDev_PHPUnit Tip #4

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 #4: Named Parameters

The advantage of YAML files for configuration is supposed to be easy readability. But if a data provider looks like this, there’s not so much readability left:

-
  - 7
  - 1
  -
    5: 7
    6: 9
-
  - 7
  - 1
  -
    5: 8
    6: 10

Technically the same, but way more maintainable:

Bundle_X_A1_B2:
  product_id: 7
  qty: 1
  bundle_selections_by_option:
    5: 7
    6: 9
Bundle_X_A2_B2:
  product_id: 7
  qty: 1
  bundle_selections_by_option:
    5: 8
    6: 10

You can at least guess, that this one is about adding bundle products to the cart, and if you know it, the test data is easy to understand, without having to look at the source code.

Another positive effect is, that for failed tests PHPUnit doesn’t show messages like TestCase::test() with data set #1 anymore, but for example TestCase::test() with data set "Bundle_X_A1_B2"

EcomDev_PHPUnit Tip #3

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 #3 Shared Data Providers

Did you ever wonder, why you can specify the file name for expectations and fixtures, but for data providers you seem to be limited to the default “test name dot yaml”? The simple reason is, @dataProvider is a native feature of PHPUnit and its parameter actually must be a method name.

So @dataProvider dataProvider means, the method EcomDev_PHPUnit_Test_Case::dataProvider() is used as data provider:

    /**
     * Implements default data provider functionality,
     * returns array data loaded from Yaml file with the same name as test method
     *
     * @param string $testName
     * @return array
     */
    public function dataProvider($testName)
    {
        return TestUtil::dataProvider(get_called_class(), $testName);
    }

But EcomDev_PHPUnit also has a way to specify the file name for the data provider explicitly, thus allows shared providers:

/**
 * @dataProvider dataProvider
 * @dataProviderFile customFileName.yaml
 */
public function testSomething($something)

EcomDev_PHPUnit Tip #2

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 #2: Expectation Keys

This is a short one: expected('works %s sprintf', 'like').

Which expectations should be loaded, usually depends on input data, so if your expectation file looks like this:

- product-1-qty-10:
  - answer: 42
- product-2-qty-10:
  - answer: 42

you can load it in the test like this:

/**
 * @test
 * @loadExpectation
 * @loadFixture
 * @dataProvider dataProvider
 */
public function testSomething($productId, $qty)
{
  $expectedAnswer = $this->expected('product-%s-qty-%s', $productId, $qty);
}

EcomDev_PHPUnit Tip #1

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 #1: Reset Global State

Something that makes testing with Magento quite difficult, is the liberal use of global state, in form of singletons and registry. They are not reset between tests, but EcomDev_PHPUnit allows explicit resetting with annotations.

/**
 * @singleton checkout/session
 * @helper tax
 * @registry current_product
 */
public function testSomething()

The parameters are the same as for Mage::getSingleton(), Mage::helper() and Mage::registry().

It is recommended to reset all singletons and registry values that are used during the test, not only after you get conflicts. Especially resetting used session singletons is important, regardless if they are mocked in the current test. Only for stateless helpers, i.e. those that don’t have own attributes, resetting is not necessary.