Category: EcomDev_PHPUnit

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.

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 #13: Speed up EAV fixtures

If you use the EAV fixtures to create products, categories and customers for tests, the fixture processor or EcomDev_PHPUnit makes a backup of the according tables before each test and restores it afterwards. Since the “magento_unit_tests” test database is copied from the current Magento database by default, this can result in much unnecessary overhead.

We can speed up tests that run several minutes many times over, by cleaning up the EAV tables in the test database. To do so, delete all rows in the entity main tables of the test DB, the associated attributes etc. are deleted automatically with triggers. With one exception: Do not delete the default root category:

delete from catalog_product_entity;
delete from catalog_category_entity where entity_id > 2;
delete from customer_entity;

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 #12: Cache

You can turn caches on and off per test, using the following annotations:

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 #11: Minimal Fixtures For Product Types

Below are some example fixtures for different product types. They are as minimal as possible to create products and their relationships. In most cases you will want to add more attributes like name, visibility, status, price and stock status.

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 #10: Broken Translations

It happens that translations are not working in unit tests if you replace a helper with a mocked helper, using mockHelper() and replaceByMock(), especially in developer mode where translations only work if defined for the right module.

The module name is determined in Mage_Core_Helper_Abstract by $this->_getModuleName(), so let’s look into this method:

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.

Since there are some singletons involved, make sure to reset their state:

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');

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:

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.

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 #7: YAML Directory Fallback

YAML files for fixtures, expectations and data providers are expected in the following scheme by default, where in this example Importer.php contains the test case and testImport is the test method:

Instead of the method name the file name of the YAML file can also be stated explicitly, like in this example where another test also uses fixtures/testImport.yaml (how this also works for data providers, see 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 #6: Fixture Rollback

If you use fixtures, the fixture data is removed from the database after the corresponding test finishes. But it’s important to note, that there is no transaction rollback, instead all tables affected by the fixture will be truncated after the test.

This has some implications:

You shouldn’t ever use table fixtures with tables that contain important core data, like core_config_data or eav_attribute

Data in tables, not contained in the fixture, stay. You can trigger deletion of data created during test with an empty fixture, for example for quotes and orders:

tables:
sales/quote: []
sales/order: []

If this behavior is not desired, you should clean up behind yourself, i.e. delete created data in a tearDown method.

Don’t rely too much on data present in the original database, as other tests might overwrite and eventually delete it with their fixtures

If you use shared fixtures with @loadSharedFixture all data in the shared fixture is only created and removed once. All tables affected by a shared fixture will not be cleaned up in between at all, even if other normal fixtures add data. My advice: Use shared fixtures with caution, or better not at all.

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 #5: Secure Area

Problem: test cases extending EcomDev_PhpUnit_Test_Case_Controller with customer fixture fail with Cannot complete this operation from non-admin area because Magento is in area=frontend mode during tearDown and does not allow deletion of customers. The same problem occurs when you try to delete customers in a test outside of an adminhtml context.

The customer model checks if the isSecureArea flag is set in the Magento registry, so to solve the problem, we set this flag in the test. There are two possible ways to do it: