Magento php unit testing

PHPUnit testing has become a good practice in PHP development. It can be used for checking the thin and vulnerable places in your code, and spare time for bug tracking and testing during the development progress. Magento itself is quite complicated PHP structure. So, sometimes it is really hard to find a connection between the bug and its reason. We think, it can be really useful practice to perform unit testing during Magento extension development. This brief article is aimed to show the basic structure and approach of using PHP unit tests in Magento.

First of all, we need to get PHPUnit running in our development environment. Actually, there are a lot of articles dedicated to PHPUnit installation. So, let’s just get the terse console commands list from official website:

wget https://phar.phpunit.de/phpunit.phar
chmod +x phpunit.phar
mv phpunit.phar /usr/local/bin/phpunit

Let’s assume that you’ve successfully installed PHPUnit and can run it from the console in any place you want in your development environment. Navigate to your Magento project root directory. First off all, create a proper directory structure for the future tests. Start from making a tests directory and a unit directory in it. The unit directory will contain anything we will need for unit tests. Moreover, the tests directory can also contain other kind of tests in its respective directories (js-tests, for example). Navigate to your-magento-location/tests/unit and create two files there (you can also find an approach with putting these files to the your-magento-location/tests/unit/framework directory, but we will avoid it here):

  1. your-magento-location/tests/unit/autoload.php :
    <?php
    
    ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR 
         . dirname(__FILE__) . '/../../app' . PATH_SEPARATOR . dirname(__FILE__));
    //Set custom memory limit
    ini_set('memory_limit', '512M');
    //Include Magento libraries
    require_once 'Mage.php';
    //Start the Magento application
    Mage::app('default');
    //Avoid issues "Headers already send"
    session_start();
  2. your-magento-location/tests/unit/phpunit.xml :
    <?xml version="1.0" encoding="UTF-8" ?>
    <phpunit backupGlobals="false"
             backupStaticAttributes="false"
             colors="true"
             convertErrorsToExceptions="true"
             convertNoticesToExceptions="true"
             convertWarningsToExceptions="true"
             processIsolation="false"
             stopOnFailure="false"
             syntaxCheck="true"
             bootstrap="./autoload.php">
    <testsuite name="Magento Unit Test">
        <directory>testsuite</directory>
    </testsuite>
    <filter>
        <whitelist>
            <directory>../../app/code/local</directory>
        </whitelist>
    </filter>
    </phpunit>

Create a testsuite directory in your-magento-location/tests/unit/ – it will contain all the module tests in the module respective structure, so you can create a unit test file for each PHP file in your extension. As a result, your folder structure should look like this:

article-folders

Now, we can create a proper test file for each PHP file in your module. Simply put it to the respective folder of your-magento-location/tests/unit/testsuite/Company/Module and name it FilefortestingnameTest.php. For example, your test for block your-magento-location/app/code/local/Company/Module/Block/Blockname.php will be named your-magento-location/tests/unit/testsuite/Company/Module/Block/BlocknameTest.php and look like this:

<?php

class Company_Module_Block_BlocknameTest extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {
    	/* You'll have to load Magento app in any test classes in this method */
    	$app = Mage::app('default');
    	/* You will need a layout for block tests */
        $this->_layout = $app->getLayout();
        /* Let's create the block instance for further tests */
        $this->_block = new Company_Module_Block_Blockname;
        /* We are required to set layouts before we can do anything with blocks */
        $this->_block->setLayout($this->_layout);
    }

    public function testFirstMethod()
    {
    	/*Here goes the assertions for your block first method*/
    }

    public function testSecondMethod()
    {
    	/*Here goes the assertions for your block second method*/
    }
}

Tests for other module components are pretty similar to this one. After your tests are ready, you can try to run them from your console:

cd your-magento-location/tests/unit/
phpunit

You will get something like this:

article-console

We hope you’ll find this information useful, and leave your feedback in the comments below.