WHO AM I • Alistair Stead • Technical Team Lead @ Ibuildings UK / Session Digital • Lead Magento projects for 3663, WMI, Kookai and others • Over 3 years experience with Magento • Zend Certified Engineer • Over 11 years commercial experience developing in PHP Wednesday, 9 February 2011
class DataCash_Dpg_Model_ConfigTest extends Ibuildings_Mage_Test_PHPUnit_TestCase { /** * Member variable to hold reference to the opbject under test * * @var DataCash_Dpg_Model_Config **/ protected $_object; /** * Setup fixtures and dependencies * * @return void * @author Alistair Stead **/ public function setUp() { parent::setUp(); $this->_object = Mage::getSingleton('dpg/config'); } Wednesday, 9 February 2011
class DataCash_Dpg_Model_ConfigTest extends Ibuildings_Mage_Test_PHPUnit_TestCase { /** * Member variable to hold reference to the opbject under test * * @var DataCash_Dpg_Model_Config **/ protected $_object; /** * Setup fixtures and dependencies * * @return void * @author Alistair Stead **/ public function setUp() { parent::setUp(); $this->_object = Mage::getSingleton('dpg/config'); } Wednesday, 9 February 2011
class DataCash_Dpg_Model_ConfigTest extends Ibuildings_Mage_Test_PHPUnit_TestCase { /** * Member variable to hold reference to the opbject under test * * @var DataCash_Dpg_Model_Config **/ protected $_object; /** * Setup fixtures and dependencies * * @return void * @author Alistair Stead **/ public function setUp() { parent::setUp(); $this->_object = Mage::getSingleton('dpg/config'); } Wednesday, 9 February 2011
/** * getTransactionTypesReturnsArray * @author Alistair Stead * @test */ public function getTransactionTypesReturnsArray() { $result = $this->_object->getTansactionTypes(); $this->assertTrue(is_array($result), 'No array returned'); $this->assertEquals(count($result), 2, 'More transaction types than expected'); $this->assertArrayHasKey( 'A', $result, 'The array does not contain A' ); $this->assertArrayHasKey( 'P', $result, 'The array does not contain P' ); } // getTransactionTypesReturnsArray Wednesday, 9 February 2011
/** * getTransactionTypesReturnsArray * @author Alistair Stead * @test */ public function getTransactionTypesReturnsArray() { $result = $this->_object->getTansactionTypes(); $this->assertTrue(is_array($result), 'No array returned'); $this->assertEquals(count($result), 2, 'More transaction types than expected'); $this->assertArrayHasKey( 'A', $result, 'The array does not contain A' ); $this->assertArrayHasKey( 'P', $result, 'The array does not contain P' ); } // getTransactionTypesReturnsArray Wednesday, 9 February 2011
/** * helperFactoryReturnsTheExpectedClass * @author Alistair Stead * @test */ public function helperFactoryReturnsTheExpectedClass() { $this->assertInstanceOf('Ibuildings_ContactsDepartment_Helper_Data', $this->_helper); } // helperFactoryReturnsTheExpectedClass /** * getDepartmentOptionsShouldReturnAssociativeArray * @author Alistair Stead * @test */ public function getDepartmentOptionsShouldReturnAssociativeArray() { foreach ($this->_helper->getDepartmentOptions() as $option) { $this->assertArrayHasKey( 'value', $option, 'The options array does not have a value' ); $this->assertArrayHasKey( 'label', $option, 'The options array does not have a label' ); } } // getDepartmentOptionsShouldReturnAssociativeArray Wednesday, 9 February 2011
/** * helperFactoryReturnsTheExpectedClass * @author Alistair Stead * @test */ public function helperFactoryReturnsTheExpectedClass() { $this->assertInstanceOf('Ibuildings_ContactsDepartment_Helper_Data', $this->_helper); } // helperFactoryReturnsTheExpectedClass /** * getDepartmentOptionsShouldReturnAssociativeArray * @author Alistair Stead * @test */ public function getDepartmentOptionsShouldReturnAssociativeArray() { foreach ($this->_helper->getDepartmentOptions() as $option) { $this->assertArrayHasKey( 'value', $option, 'The options array does not have a value' ); $this->assertArrayHasKey( 'label', $option, 'The options array does not have a label' ); } } // getDepartmentOptionsShouldReturnAssociativeArray Wednesday, 9 February 2011
/** * helperFactoryReturnsTheExpectedClass * @author Alistair Stead * @test */ public function helperFactoryReturnsTheExpectedClass() { $this->assertInstanceOf('Ibuildings_ContactsDepartment_Helper_Data', $this->_helper); } // helperFactoryReturnsTheExpectedClass /** * getDepartmentOptionsShouldReturnAssociativeArray * @author Alistair Stead * @test */ public function getDepartmentOptionsShouldReturnAssociativeArray() { foreach ($this->_helper->getDepartmentOptions() as $option) { $this->assertArrayHasKey( 'value', $option, 'The options array does not have a value' ); $this->assertArrayHasKey( 'label', $option, 'The options array does not have a label' ); } } // getDepartmentOptionsShouldReturnAssociativeArray Wednesday, 9 February 2011
/** * Provide a public method to allow the internal Request object * to be set at runtime. This can be used to inject a testing request object * * @return void * @author Alistair Stead **/ public function setRequest(Zend_Controller_Request_Abstract $request) { $this->_request = $request; } /** * Retrieve request object * * @return Mage_Core_Controller_Request_Http */ public function getRequest() { if (empty($this->_request)) { $this->_request = new Mage_Core_Controller_Request_Http(); } return $this->_request; } Wednesday, 9 February 2011
/** * Provide a public method to allow the internal Request object * to be set at runtime. This can be used to inject a testing request object * * @return void * @author Alistair Stead **/ public function setRequest(Zend_Controller_Request_Abstract $request) { $this->_request = $request; } /** * Retrieve request object * * @return Mage_Core_Controller_Request_Http */ public function getRequest() { if (empty($this->_request)) { $this->_request = new Mage_Core_Controller_Request_Http(); } return $this->_request; } Wednesday, 9 February 2011
/** * Provide a public method to allow the protected internal Response object * to be set at runtime. This can be used to inject a testing response object * * @return void * @author Alistair Stead **/ public function setResponse(Zend_Controller_Response_Abstract $response) { $this->_response = $response; } /** * Retrieve response object * * @return Zend_Controller_Response_Http */ public function getResponse() { if (empty($this->_response)) { $this->_response = new Mage_Core_Controller_Response_Http(); $this->_response->headersSentThrowsException = Mage::$headersSentThrowsException; $this->_response->setHeader("Content-Type", "text/html; charset=UTF-8"); } return $this->_response; } Wednesday, 9 February 2011
/** * Provide a public method to allow the protected internal Response object * to be set at runtime. This can be used to inject a testing response object * * @return void * @author Alistair Stead **/ public function setResponse(Zend_Controller_Response_Abstract $response) { $this->_response = $response; } /** * Retrieve response object * * @return Zend_Controller_Response_Http */ public function getResponse() { if (empty($this->_response)) { $this->_response = new Mage_Core_Controller_Response_Http(); $this->_response->headersSentThrowsException = Mage::$headersSentThrowsException; $this->_response->setHeader("Content-Type", "text/html; charset=UTF-8"); } return $this->_response; } Wednesday, 9 February 2011
/** * Bootstrap the Mage application in a similar way to the procedure * of index.php * * Then sets test case request and response objects in Mage_Core_App, * and disables returning the response. * * @return void * @author Alistair Stead */ public function mageBootstrap() { Mage::reset(); if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) { Mage::setIsDeveloperMode(true); } // Store or website code $this->mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : ''; // Run store or run website $this->mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store'; // Initialize the Mage App and inject the testing request & response Mage::app($this->mageRunCode, $this->mageRunType, $this->options); Mage::app()->setRequest(new Ibuildings_Mage_Controller_Request_HttpTestCase); Mage::app()->setResponse(new Ibuildings_Mage_Controller_Response_HttpTestCase); } Wednesday, 9 February 2011
/** * Bootstrap the Mage application in a similar way to the procedure * of index.php * * Then sets test case request and response objects in Mage_Core_App, * and disables returning the response. * * @return void * @author Alistair Stead */ public function mageBootstrap() { Mage::reset(); if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) { Mage::setIsDeveloperMode(true); } // Store or website code $this->mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : ''; // Run store or run website $this->mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store'; // Initialize the Mage App and inject the testing request & response Mage::app($this->mageRunCode, $this->mageRunType, $this->options); Mage::app()->setRequest(new Ibuildings_Mage_Controller_Request_HttpTestCase); Mage::app()->setResponse(new Ibuildings_Mage_Controller_Response_HttpTestCase); } Wednesday, 9 February 2011
/** * Bootstrap the Mage application in a similar way to the procedure * of index.php * * Then sets test case request and response objects in Mage_Core_App, * and disables returning the response. * * @return void * @author Alistair Stead */ public function mageBootstrap() { Mage::reset(); if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) { Mage::setIsDeveloperMode(true); } // Store or website code $this->mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : ''; // Run store or run website $this->mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store'; // Initialize the Mage App and inject the testing request & response Mage::app($this->mageRunCode, $this->mageRunType, $this->options); Mage::app()->setRequest(new Ibuildings_Mage_Controller_Request_HttpTestCase); Mage::app()->setResponse(new Ibuildings_Mage_Controller_Response_HttpTestCase); } Wednesday, 9 February 2011
Ibuildings_Mage_Controller_Response_HttpTestCase Controller Ibuildings_Mage_Controller_Request_HttpTestCase View Model Ibuildings_Mage_Controller_Response_HttpTestCase Wednesday, 9 February 2011
/** * Mage_Catalog_IndexControllerTest * * @package Mage_Catalog * @subpackage Mage_Catalog_Test * * * @uses PHPUnit_Framework_Magento_TestCase */ class Mage_Catalog_IndexControllerTest extends Ibuildings_Mage_Test_PHPUnit_ControllerTestCase { /** * theIndexActionShouldRedirectToRoot * @author Alistair Stead * @test */ public function theIndexActionShouldRedirectToRoot() { $this->dispatch('/'); $this->assertRoute('cms', "The expected cms route has not been matched"); $this->assertAction('index', "The index action has not been called"); $this->assertController('index', "The expected controller is not been used"); $this->assertQuery('div.nav-container', 'The site navigation is not present on the home page'); } // theIndexActionShouldRedirectToRoot } Wednesday, 9 February 2011
/** * Mage_Catalog_IndexControllerTest * * @package Mage_Catalog * @subpackage Mage_Catalog_Test * * * @uses PHPUnit_Framework_Magento_TestCase */ class Mage_Catalog_IndexControllerTest extends Ibuildings_Mage_Test_PHPUnit_ControllerTestCase { /** * theIndexActionShouldRedirectToRoot * @author Alistair Stead * @test */ public function theIndexActionShouldRedirectToRoot() { $this->dispatch('/'); $this->assertRoute('cms', "The expected cms route has not been matched"); $this->assertAction('index', "The index action has not been called"); $this->assertController('index', "The expected controller is not been used"); $this->assertQuery('div.nav-container', 'The site navigation is not present on the home page'); } // theIndexActionShouldRedirectToRoot } Wednesday, 9 February 2011
/** * Mage_Catalog_IndexControllerTest * * @package Mage_Catalog * @subpackage Mage_Catalog_Test * * * @uses PHPUnit_Framework_Magento_TestCase */ class Mage_Catalog_IndexControllerTest extends Ibuildings_Mage_Test_PHPUnit_ControllerTestCase { /** * theIndexActionShouldRedirectToRoot * @author Alistair Stead * @test */ public function theIndexActionShouldRedirectToRoot() { $this->dispatch('/'); $this->assertRoute('cms', "The expected cms route has not been matched"); $this->assertAction('index', "The index action has not been called"); $this->assertController('index', "The expected controller is not been used"); $this->assertQuery('div.nav-container', 'The site navigation is not present on the home page'); } // theIndexActionShouldRedirectToRoot } Wednesday, 9 February 2011
/** * theAdminRouteAccessesTheAdminApplicationArea * @author Alistair Stead * @test */ public function theAdminRouteAccessesTheAdminApplicationArea() { $this->dispatch('admin/'); $this->assertRoute('adminhtml', "The expected route has not been matched"); $this->assertAction('login', "The login form should be presented"); $this->assertController('index', "The expected controller is not been used"); } // theAdminRouteAccessesTheAdminApplicationArea /** * theIndexActionDisplaysLoginForm * @author Alistair Stead * @group login * @test */ public function theIndexActionDisplaysLoginForm() { $this->dispatch('admin/index/'); $this->assertQueryCount('form#loginForm', 1); } // theIndexActionDisplaysLoginForm Wednesday, 9 February 2011
/** * theAdminRouteAccessesTheAdminApplicationArea * @author Alistair Stead * @test */ public function theAdminRouteAccessesTheAdminApplicationArea() { $this->dispatch('admin/'); $this->assertRoute('adminhtml', "The expected route has not been matched"); $this->assertAction('login', "The login form should be presented"); $this->assertController('index', "The expected controller is not been used"); } // theAdminRouteAccessesTheAdminApplicationArea /** * theIndexActionDisplaysLoginForm * @author Alistair Stead * @group login * @test */ public function theIndexActionDisplaysLoginForm() { $this->dispatch('admin/index/'); $this->assertQueryCount('form#loginForm', 1); } // theIndexActionDisplaysLoginForm Wednesday, 9 February 2011
/** * theAdminRouteAccessesTheAdminApplicationArea * @author Alistair Stead * @test */ public function theAdminRouteAccessesTheAdminApplicationArea() { $this->dispatch('admin/'); $this->assertRoute('adminhtml', "The expected route has not been matched"); $this->assertAction('login', "The login form should be presented"); $this->assertController('index', "The expected controller is not been used"); } // theAdminRouteAccessesTheAdminApplicationArea /** * theIndexActionDisplaysLoginForm * @author Alistair Stead * @group login * @test */ public function theIndexActionDisplaysLoginForm() { $this->dispatch('admin/index/'); $this->assertQueryCount('form#loginForm', 1); } // theIndexActionDisplaysLoginForm Wednesday, 9 February 2011
/** * theAdminRouteAccessesTheAdminApplicationArea * @author Alistair Stead * @test */ public function theAdminRouteAccessesTheAdminApplicationArea() { $this->dispatch('admin/'); $this->assertRoute('adminhtml', "The expected route has not been matched"); $this->assertAction('login', "The login form should be presented"); $this->assertController('index', "The expected controller is not been used"); } // theAdminRouteAccessesTheAdminApplicationArea /** * theIndexActionDisplaysLoginForm * @author Alistair Stead * @group login * @test */ public function theIndexActionDisplaysLoginForm() { $this->dispatch('admin/index/'); $this->assertQueryCount('form#loginForm', 1); } // theIndexActionDisplaysLoginForm Wednesday, 9 February 2011
/** * theAdminRouteAccessesTheAdminApplicationArea * @author Alistair Stead * @test */ public function theAdminRouteAccessesTheAdminApplicationArea() { $this->dispatch('admin/'); $this->assertRoute('adminhtml', "The expected route has not been matched"); $this->assertAction('login', "The login form should be presented"); $this->assertController('index', "The expected controller is not been used"); } // theAdminRouteAccessesTheAdminApplicationArea /** * theIndexActionDisplaysLoginForm * @author Alistair Stead * @group login * @test */ public function theIndexActionDisplaysLoginForm() { $this->dispatch('admin/index/'); $this->assertQueryCount('form#loginForm', 1); } // theIndexActionDisplaysLoginForm Wednesday, 9 February 2011
public function mageBootstrap() { Mage::reset(); if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) { Mage::setIsDeveloperMode(true); } // Store or website code $this->mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : ''; // Run store or run website $this->mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store'; // Initialize the Mage App and inject the testing request & response Mage::app($this->mageRunCode, $this->mageRunType, $this->options); Mage::app()->setRequest(new Ibuildings_Mage_Controller_Request_HttpTestCase); Mage::app()->setResponse(new Ibuildings_Mage_Controller_Response_HttpTestCase); // Rewrite the core classes at runtime to prevent emails from being sent Mage::getConfig()->setNode('global/models/core/rewrite/email_template', 'Ibuildings_Test_Model_Email_Template'); // This is a hack to get the runtime config changes to take effect Mage::getModel('core/email_template'); } Wednesday, 9 February 2011
public function mageBootstrap() { Mage::reset(); if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) { Mage::setIsDeveloperMode(true); } // Store or website code $this->mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : ''; // Run store or run website $this->mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store'; // Initialize the Mage App and inject the testing request & response Mage::app($this->mageRunCode, $this->mageRunType, $this->options); Mage::app()->setRequest(new Ibuildings_Mage_Controller_Request_HttpTestCase); Mage::app()->setResponse(new Ibuildings_Mage_Controller_Response_HttpTestCase); // Rewrite the core classes at runtime to prevent emails from being sent Mage::getConfig()->setNode('global/models/core/rewrite/email_template', 'Ibuildings_Test_Model_Email_Template'); // This is a hack to get the runtime config changes to take effect Mage::getModel('core/email_template'); } Wednesday, 9 February 2011
/** * submittingForgotPasswordWithValidEmailReturnsSuccess * @author Alistair Stead * @group password * @test * */ public function submittingForgotPasswordWithValidEmailReturnsSuccess() { $this->request->setMethod('POST') ->setPost(array('email' => $this->email)); $this->dispatch('admin/index/forgotpassword/'); $this->assertQueryCount('li.success-msg', 1); $this->assertQueryContentContains('li.success-msg', 'A new password was sent to your email address. Please check your email and click Back to Login.'); // Test that the email contains the correct data $emailContent = $this->getResponseEmail() ->getBodyHtml() ->getContent(); // Overriding the response body to be able to use the standard content assertions $this->response->setBody($emailContent); // The email content addresses the fixture user $this->assertQueryContentContains('body', "Dear $this->firstName $this->lastName"); // The fixture users password has been changed $this->assertNotQueryContentContains('body', $this->password); } // submittingForgotPasswordWithValidEmailReturnsSuccess Wednesday, 9 February 2011
/** * submittingForgotPasswordWithValidEmailReturnsSuccess * @author Alistair Stead * @group password * @test * */ public function submittingForgotPasswordWithValidEmailReturnsSuccess() { $this->request->setMethod('POST') ->setPost(array('email' => $this->email)); $this->dispatch('admin/index/forgotpassword/'); $this->assertQueryCount('li.success-msg', 1); $this->assertQueryContentContains('li.success-msg', 'A new password was sent to your email address. Please check your email and click Back to Login.'); // Test that the email contains the correct data $emailContent = $this->getResponseEmail() ->getBodyHtml() ->getContent(); // Overriding the response body to be able to use the standard content assertions $this->response->setBody($emailContent); // The email content addresses the fixture user $this->assertQueryContentContains('body', "Dear $this->firstName $this->lastName"); // The fixture users password has been changed $this->assertNotQueryContentContains('body', $this->password); } // submittingForgotPasswordWithValidEmailReturnsSuccess Wednesday, 9 February 2011
/** * submittingForgotPasswordWithValidEmailReturnsSuccess * @author Alistair Stead * @group password * @test * */ public function submittingForgotPasswordWithValidEmailReturnsSuccess() { $this->request->setMethod('POST') ->setPost(array('email' => $this->email)); $this->dispatch('admin/index/forgotpassword/'); $this->assertQueryCount('li.success-msg', 1); $this->assertQueryContentContains('li.success-msg', 'A new password was sent to your email address. Please check your email and click Back to Login.'); // Test that the email contains the correct data $emailContent = $this->getResponseEmail() ->getBodyHtml() ->getContent(); // Overriding the response body to be able to use the standard content assertions $this->response->setBody($emailContent); // The email content addresses the fixture user $this->assertQueryContentContains('body', "Dear $this->firstName $this->lastName"); // The fixture users password has been changed $this->assertNotQueryContentContains('body', $this->password); } // submittingForgotPasswordWithValidEmailReturnsSuccess Wednesday, 9 February 2011
/** * submittingForgotPasswordWithValidEmailReturnsSuccess * @author Alistair Stead * @group password * @test * */ public function submittingForgotPasswordWithValidEmailReturnsSuccess() { $this->request->setMethod('POST') ->setPost(array('email' => $this->email)); $this->dispatch('admin/index/forgotpassword/'); $this->assertQueryCount('li.success-msg', 1); $this->assertQueryContentContains('li.success-msg', 'A new password was sent to your email address. Please check your email and click Back to Login.'); // Test that the email contains the correct data $emailContent = $this->getResponseEmail() ->getBodyHtml() ->getContent(); // Overriding the response body to be able to use the standard content assertions $this->response->setBody($emailContent); // The email content addresses the fixture user $this->assertQueryContentContains('body', "Dear $this->firstName $this->lastName"); // The fixture users password has been changed $this->assertNotQueryContentContains('body', $this->password); } // submittingForgotPasswordWithValidEmailReturnsSuccess Wednesday, 9 February 2011
MAGE-TEST IS OPEN SOURCE • Use Mage-Test to test your development projects • Use Mage-Test to test you extensions • Contribute tests for Magento • Build up the coverage of the Magento codebase • Take advantage of core tests for regression testing Wednesday, 9 February 2011