Lesti_Fpc has changed in the last month. Some of the changes are part of the code quality. Today I would like to present the tools, that I use to raise the quality of my Magento extension.
A Continuous integration is pretty important. It runs my tests and code sniffers after every push. Travis CI is the top dog for open source projects. Travis CI is a continuous integration platform for open source projects. I just added a .travis.yml to the root of my Github Repository.
language: php
php:
- 5.3
- 5.4
env:
- MAGE=magento-1-9-0-1
- MAGE=magento-1-8-1-0
- MAGE=magento-1-7-0-2
- MAGE=magento-1-6-2-0
- MAGE=magento-1-5-1-0
install:
- cp -f .travis/composer.json composer.json
- composer install --dev
- curl https://gordonlesti.com/"$MAGE".tar.gz | tar xz
- mv $MAGE magento
- cd magento
- wget https://raw.githubusercontent.com/colinmollenhour/modman/master/modman
- chmod +x modman
- ./modman init
- cd ..
before_script:
- mkdir -p build/logs
- mysql -e 'create database `magento`;'
- mysql -utravis magento < magento/var/magento.sql
- mysql -e 'create database `magento_test`;'
- mysql -utravis magento_test < magento/var/magento_test.sql
- cd magento
- ./modman link ./../../Lesti_Fpc
- ./modman clone https://github.com/EcomDev/EcomDev_PHPUnit.git
- cd ..
script:
- php vendor/bin/phpcs --standard=Zend app/
- php vendor/bin/phpmd app/ text codesize,design,unusedcode
- cd magento && php ../vendor/bin/phpunit --coverage-clover ../build/logs/clover.xml && cd ..
after_script:
- php vendor/bin/coveralls
As you can see, I did run my tests against PHP 5.3 and 5.4. The tested Magento versions are 1.5, 1.6, 1.7, 1.8 and
1.9. I have created blank Magento shops with the super awesome tool
n98-magerun. After that I have
deleted the media folder, created mysql dumps of the shop and the testing database. The two databases and the code are
compressed in the following files:I use Composer to installing all that testing and quality tools. Here is my .travis/composer.json
{
"require-dev": {
"phpunit/phpunit": "*",
"phpmd/phpmd" : "*",
"squizlabs/php_codesniffer": "*",
"satooshi/php-coveralls": "dev-master"
}
}
In front of the unit tests, I did check if the code ensures the common styling guidelines. I did use PHPCS with the Zend coding standard. This is a pretty old standard, but it mostly fits the coding style of Magento. And that is the important part for other developers, if they maintain my code. Maybe I will change to the coding standard of Firegento in the future. With PHPMD I did check things like unused variables, maximum number of methods in a class and so on.
To test an PHP project, you should use PHPUnit. But in Magento it's damm hard to test. Out of this reason, Ivan Chepurnyi has created EcomDev_PHPUnit. It will help you to write unit tests for Magento. I did install EcomDev_PHPUnit with modman from Colin Mollenhour. Just as example, here is app/code/community/Lesti/Fpc/Test/Helper/Data.php to test app/code/community/Lesti/Fpc/Helper/Data.php.
<?php
/**
* Lesti_Fpc (http:gordonlesti.com/lestifpc)
*
* PHP version 5
*
* @link https://github.com/GordonLesti/Lesti_Fpc
* @package Lesti_Fpc
* @author Gordon Lesti <info@gordonlesti.com>
* @copyright Copyright (c) 2013-2014 Gordon Lesti (http://gordonlesti.com)
* @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
*/
/**
* Test case for Lesti_Fpc_Helper_Data
*/
class Lesti_Fpc_Test_Helper_Data extends Lesti_Fpc_Test_TestCase
{
/**
* @var Lesti_Fpc_Helper_Data
*/
protected $_helper;
protected function setUp()
{
parent::setUp();
$this->_helper = Mage::helper('fpc');
}
/**
* @test
* @loadFixture get_cacheable_actions.yaml
*/
public function testGetCacheableActions()
{
$this->assertEquals(
array('cms_index_index', 'cms_page_view', 'catalog_product_view'),
$this->_helper->getCacheableActions()
);
}
/**
* @test
* @loadFixture get_cacheable_actions_empty.yaml
*/
public function testGetCacheableActionsEmpty()
{
$this->assertEquals(array(), $this->_helper->getCacheableActions());
}
/**
* @test
* @loadFixture get_bypass_handles.yaml
*/
public function testGetBypassHandles()
{
$this->assertEquals(
array('some_handle', 'logged_in', 'CATEGORY_25'),
$this->_helper->getBypassHandles()
);
}
/**
* @test
* @loadFixture get_bypass_handles_empty.yaml
*/
public function testGetBypassHandlesEmpty()
{
$this->assertEquals(array(), $this->_helper->getBypassHandles());
}
/**
* @test
* @loadFixture get_refresh_actions.yaml
*/
public function testGetRefreshActions()
{
$this->assertEquals(
array(
'checkout_cart_add',
'checkout_cart_delete',
'checkout_cart_updatePost'
),
$this->_helper->getRefreshActions()
);
}
/**
* @test
* @loadFixture get_refresh_actions_empty.yaml
*/
public function testGetRefreshActionsEmpty()
{
$this->assertEquals(array(), $this->_helper->getRefreshActions());
}
/**
* Test that URI params can be matched by RegEx
*
* @test
* @loadFixture regex_uri_params.yaml
* @dataProvider dataProvider
*/
public function testRegexUriParams(
$uriParamSets = array(),
$expectedCount = 0
)
{
$actualKeys = array();
foreach ($uriParamSets as $uriParams) {
$this->_resetParams();
Mage::app()->getRequest()->setParams($uriParams);
$actualKeys[] = $this->_helper->getKey();
}
$this->assertCount(
$expectedCount,
array_unique($actualKeys),
sprintf('%d different keys expected', $expectedCount)
);
}
/**
* @test
* @loadFixture can_cache_request.yaml
* @dataProvider dataProvider
*/
public function testCanCacheRequest($method, $expected, $params = array())
{
Mage::app()->getRequest()->clearParams();
Mage::app()->getRequest()->setMethod($method);
Mage::app()->getRequest()->setParams($params);
$this->assertEquals(
(bool) $expected,
$this->_helper->canCacheRequest()
);
}
/**
* @test
*/
public function getFullActionName()
{
Mage::app()->getRequest()->setRouteName('f');
Mage::app()->getRequest()->setControllerName('p');
Mage::app()->getRequest()->setActionName('c');
$this->assertEquals('f_p_c', $this->_helper->getFullActionName());
}
/**
* Reset parameters in Magento request and FPC
*/
protected function _resetParams()
{
if (Mage::registry(Lesti_Fpc_Helper_Data::REGISTRY_KEY_PARAMS)) {
Mage::unregister(Lesti_Fpc_Helper_Data::REGISTRY_KEY_PARAMS);
}
Mage::app()->getRequest()->clearParams();
}
}
PHPUnit creates coverage clover files, that contain information about my code coverage. Just to be sure, that the code coverage increases, I did use Coveralls. This service for open source projects creates comments on pull requests, if the code coverage increased or decreased.