Unit Testing Magento 1.x Modules / 1: Getting Started

Feb 20 · 6 min read
“Code without tests is broken by design” Jacob Kaplan-Moss

Unit tests are usually disregarded in the Magento 1 module development workflow. The setup can be very complex and the overhead discourages developers, since the time required almost never fits into the working schedule. Unfortunately, it is impossible to establish a solid CI/CD workflow without tests: the risk to introduce new bugs with every commit, especially when collaborating with other team members, is just too high.

Even if the documentation is scattered all over the web and you have to figure out how to solve random issues here and there, writing solid unit test suites for Magento 1 modules is actually possible. Even more, it is absolutely necessary to work with test suites: it will help you spend most of your time as a developer building new amazing software, rather than debugging obscure issues on the server after the umpteenth break in production.

In 2019, there are still plenty of shops running Magento 1 and a transition to version 2 is anything but seamless. The Magento team announced they will extend the support for the 1.9 releases through June 2020. Magento 1 is not going to disappear from the web soon: if you haven’t already, it’s time to start testing right now. Quality assurance and smooth development/testing/release cycles are needed today more than ever.

Here are some things I’ve learnt about unit testing Magento 1.x. I will assume you already have a working experience of Magento and know how to deal with composer, phpunit and modman.

Setup a fresh Magento shop for your unit tests

The tool n98-magerun comes in very useful when we want to install a standard version of Magento and setup database and configuration files automatically. Set the following variables in your terminal (I have included some example values):

MAGENTO_DB_HOST=localhost
MAGENTO_DB_USER=root
MAGENTO_DB_PASS=password
MAGENTO_DB_NAME=magento_test_shop
MAGENTO_DB_PORT=3306
MAGENTO_VERSION=magento-mirror-1.9.3.10
MAGENTO_INSTALLATION_FOLDER=/tmp/testmagento
MAGENTO_BASE_URL=http://www.magento.test/

Then copy and paste the following command (all in one line):

n98-magerun.phar install --dbHost="${MAGENTO_DB_HOST}" --dbUser="${MAGENTO_DB_USER}" --dbPass="${MAGENTO_DB_PASS}" --dbName="${MAGENTO_DB_NAME}" --dbPort="${MAGENTO_DB_PORT}" --installSampleData=no --useDefaultConfigParams=yes --magentoVersionByName="${MAGENTO_VERSION}" --installationFolder="${MAGENTO_INSTALLATION_FOLDER}" --baseUrl="${MAGENTO_BASE_URL}"

If for any reasons the installation process ends prematurely and you have to restart it, you might have to rm -r the installation directory and drop the test database to avoid errors.

Once you see the message “Successfully installed magento”, you have a working Magento 1.9 installation for your unit tests!

Install EcomDev PHPUnit in the test shop

EcomDev_PHPUnit is an excellent module that wraps PHPUnit (the old — but still perfectly working — version 4) and connects it with Magento with a bit of patching magic and some useful helpers. The module development was discontinued in 2014 and the documentation was not updated after v0.2.0 (the latest available release is 0.3.7). If you want to get deeper into the latest (and partly undocumented) features, I definitely recommend you to check out these great posts by Fabian Schmengler.

To keep things simple and self-contained, run the following command in the Magento directory:

composer require ecomdev/ecomdev_phpunit

After the module dependencies are installed, composer will ask you to define your “Magento root directory”. Digit the full path to your Magento directory and press enter.

There is still a bit of work left to do in order to configure the testing framework. However, the configuration is a one-time procedure: once it’s done, you will be able to run the tests for all your modules on this test shop.

Create a test database and configure EcomDev_PHPUnit

We need a separate Magento database to run the unit tests, so let’s create a new one right now. Digit the following command:

mysql -uroot -p

log in with your root password, then simply create an empty database:

CREATE SCHEMA magento_unit_tests;

Now we have to tell EcomDev_PHPUnit which database to use for the tests. To setup the framework with test database and URL, I use a bash script that performs a couple of checks and configures it automatically. Save it in your Magento directory and execute it in one line with the appropriate database name and shop URL:

bash mage-install-ecomdev-phpunit.sh magento_unit_tests http://www.magento.test/

Build the database for PHPUnit

The last step to complete the environment setup is to initialize the database for the unit tests. When you run the tests in your Magento directory for the first time, EcomDev_PHPUnit runs the setup scripts for Magento and all the modules installed in the shop (if any). By the way, this is the reason why you should only use the same database to run the test in one shop, in order to avoid conflicts with different module / Magento versions.

Check the path to your PHPUnit binary and run it in your Magento directory. In our example, the vendor directory is inside the Magento directory, so just type:

vendor/bin/phpunit

If everything was set up correctly, PHPUnit will take some time (only the first time you run it!) to build the database. You will then see message like the following:

It took PHPUnit 32.45 seconds to run the Magento setup scripts and build the test database

The suite is failing because we have no test cases yet, but the test database was built successfully in 32.45 seconds. The next time, the same command should only take about half a second to complete:

If you are eager to start testing, you can download and install this simple skeleton module creator that I have made. It contains a demo unit test that asserts nothing, but makes the test suite pass (and you can reinitialize it to write your custom module, the test suite is already configured). Run these commands in the Magento directory:

modman init
modman clone https://github.com/gpaddis/module-skeleton

This time, the test suite passes and we get a nice green confirmation:

The environment is ready, we can start writing our unit tests!

Exclude broken community modules

If you setup the test database on an existing shop that already contains many open source modules, chances are that some of these have broken unit tests. These will cause PHPUnit to abort, possibly leaving you with an incomplete database and breaking the whole test suite. In this case, you can simply exclude the modules that are causing problems from the suite (you can check which tests are broken by running PHPUnit with the flag --debug). Add the following section before the closing config tag in a module’s config.xml file:

<phpunit>
<suite>
<exclude>
<Namespace_ExampleModuleOne />
<Namespace_ExampleModuleTwo />
</exclude>
</suite>
</phpunit>

The next time you run your tests, these modules will be skipped and the database setup will be completed successfully.

In the next post I explain some tips to speed up your daily testing workflow. We will take a look at some techniques to test Magento modules in isolation, from any directory, directly from your favorite IDE terminal. The goal is to test our changes as often and easy as possible, with almost zero effort.

Resources

Gianpiero Addis

Written by

Backend Developer at Lemundo

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade