SlideShare a Scribd company logo
Using of Test Driven DevelopmentPractices for MagentoIvan ChepurnyiMagento Trainer / Lead Developer
Short OverviewMeet Magento NetherlandsWrite a testImaging how your feature should work and write a failing testWrite feature quickly for receiving passed testRefactor your code and run the test againPassRun the testsFailPassWrite the codeFailRun the tests
Conventional DevelopmentMeet Magento NetherlandsYou need to write a full functionality for seeing the resultYou think that your code worksDebuggingWith every fixed issue you may produce a new oneEven if you write unit tests after implementation it doesn’t guarantee that you detect the defect.
Test Driven DevelopmentMeet Magento NetherlandsYou don’t need to implement full functionality for seeing the resultYour colleagues can use your test as learning materialThe test proofs that your code works and can be verifiedSerious defects can be fixed on early state
Defect CostsMeet Magento NetherlandsPercentage from project development hours< 1%20%> 40%Defect found at the coding stageDefect found during QA phaseDefect found after going live
Type of TestsMeet Magento NetherlandsAutomated TestRegression TestLearning TestIntegration Test
Meet Magento NetherlandsTest in IsolationMake test simpleTest erroneous situationsTest Doubles (Fake heavy resources you don’t depend on)Main Principles
EcomDev_PHPUnitMeet Magento NetherlandsMaking possible isolation of your testEasy test data loading via Yaml fixturesData providers and expectations for reusable testsEasy way of testing configuration filesEasy way for Layouts & Controllers  integration test
Simple Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Model_Productextends EcomDev_PHPUnit_Test_Case{	/** * @test  * @loadFixture * @dataProviderdataProvider */ public function priceCalculation($productId, $storeId) {       $storeId = Mage::app()->getStore($storeId)->getId();       $product = Mage::getModel('catalog/product')                              ->setStoreId($storeId) ->load($productId);       $expected = $this->expected('%s-%s', $productId, $storeId);       $this->assertEquals($expected->getFinalPrice(), $product->getFinalPrice());       $this->assertEquals($expected->getPrice(), $product->getPrice());        }}Test Case Class
Simple Test CaseMeet Magento Netherlandseav:   catalog_product:      - entity_id: 1       type_id: simple         sku: book                website_ids:                    - usa_website                    - canada_website                  price: 12.99                status: 1  # Enabled                visibility: 4  # Visible in Catalog & Search                /websites:  # Set different prices per  website           usa_website:           special_price: 9.99         german_website:                         price: 9.99           special_price: 5.99 Yaml Fixture
Simple Test CaseMeet Magento Netherlands1-2: # Product=Book Store=USAfinal_price: 9.99  price: 12.991-3: # Product=Book Store=Canadafinal_price: 12.99   price: 12.99Yaml ExpectationYaml Data Provider-  - 1  - usa-  - 1  - canada-  - 1  - germany
Event Dispatch CheckMeet Magento Netherlandsclass EcomDev_Example_Test_Model_Cms_Pageextends EcomDev_PHPUnit_Test_Case{       // …	public function testAvailableStatuses() {             Mage::getModel(‘cms/page’)->getAvailableStatuses();	       $this->assertEventDispatched(		  ‘cms_page_get_available_statuses’              );	}}Test Case
Test DoublesMeet Magento Netherlandsclass EcomDev_PHPUnit_Tes_Case_Controllerextends EcomDev_PHPUnit_Test_Case{	protected function registerCookieStub()       {                $cookie = $this->getModelMock('core/cookie', array('set', 'delete'));                $cookie->expects($this->any())                       ->method('set')                       ->will($this->returnCallback(array($this, 'setCookieCallback‘)));                $cookie->expects($this->any())                       ->method('delete‘)                       ->will($this->returnCallback(array($this, 'deleteCookieCallback‘)));                $this->replaceByMock('singleton', 'core/cookie', $cookie);                return $this;        }}Test Case
Config Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Config_Main extends EcomDev_PHPUnit_Test_Case_Config{    //….    public function testModuleVersion()    {        $this->assertModuleCodePool('local');        $this->assertModuleDepends(‘Mage_Catalog’);        $this->assertModuleVersionGreaterThan(‘0.1.0');     }}Testing Module Nodes
Config Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Config_Main extends EcomDev_PHPUnit_Test_Case_Config{    //….    public function testClassAliasDefinitions()    {        $this->assertModelAlias('catalog/product', 'Mage_Catalog_Model_Product');        $this->assertResourceModelAlias(		'catalog/product', 		‘Mage_Catalog_Model_Resource_Eav_Mysql4_Product‘	);        $this->assertBlockAlias(		'catalog/product_list', 		'Mage_Catalog_Block_Product_List‘	);     }}Testing Class Aliases
Config Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Config_Main extends EcomDev_PHPUnit_Test_Case_Config{    //….    public function testEventObservers()    {	  $this->assertEventObserverDefined(            'frontend', 'customer_login',             'catalog/product_compare_item',             'bindCustomerLogin'        );     }}Testing Event Observer Definitions
Controller Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Controller_Main extends EcomDev_PHPUnit_Test_Case_Controller{    public function testRequest()    {        $this->dispatch('cms');        $this->assertRequestDispatched();        $this->assertRequestNotForwarded();        $this->assertRequestRoute('cms/index/index');        $this->assertRequestRouteName('cms');        $this->assertRequestControllerName('index');        $this->assertRequestControllerModule('Mage_Cms');        $this->assertRequestActionName('index');    }}Testing Request
Controller Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Controller_Main        extends EcomDev_PHPUnit_Test_Case_Controller{    public function testLayout()    {        $this->dispatch('');        $this->assertLayoutHandleLoaded('cms_index_index');	$this->assertLayoutBlockCreated('right');        $this->assertLayoutBlockRendered('content');	 $this->assertLayoutBlockActionNotInvoked(	       'footer_links', 'addLink', '', array('Custom Title')        );        $this->assertLayoutBlockActionInvokedAtLeast(	       'footer_links', 'addLink', 4, '‘	);    }}Testing Layouts
What’s NextMeet Magento NetherlandsWrite automated tests for your moduleshttp://www.magentocommerce.com/magento-connect/Ecommerce%20Developers/extension/5717/ecomdev_phpunitKeep project healthy during its lifecycle with Continuous IntegrationRunning Daily BuildsRunning Unit Tests in 10 minutes after last commitHudson http://hudson-ci.orgphpUnderControlhttp://phpundercontrol.org/
Questions?ivan.chepurnyi@ecomdev.org

More Related Content

PPTX
Optimizing Magento by Preloading Data
PPTX
Magento Indexes
PPTX
Making Magento flying like a rocket! (A set of valuable tips for developers)
PPTX
Fixing Magento Core for Better Performance - Ivan Chepurnyi
PDF
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
PDF
Best Practices for Magento Debugging
PPT
Система рендеринга в Magento
PPTX
Meet Magento Belarus debug Pavel Novitsky (eng)
Optimizing Magento by Preloading Data
Magento Indexes
Making Magento flying like a rocket! (A set of valuable tips for developers)
Fixing Magento Core for Better Performance - Ivan Chepurnyi
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Best Practices for Magento Debugging
Система рендеринга в Magento
Meet Magento Belarus debug Pavel Novitsky (eng)

What's hot (20)

PDF
Get AngularJS Started!
PDF
Drupal 8 Services
PDF
購物車程式架構簡介
PPTX
Owl: The New Odoo UI Framework
PDF
Frontin like-a-backer
PDF
Integrating React.js with PHP projects
PDF
Doctrine 2
PDF
Contagion的Ruby/Rails投影片
 
PDF
TurboGears2 Pluggable Applications
PDF
Basic JSTL
PDF
Building a Pyramid: Symfony Testing Strategies
KEY
Php Unit With Zend Framework Zendcon09
PDF
Caching and Scaling WordPress using Fragment Caching
PPTX
AngularJS Directives
PDF
AngularJS Basics with Example
PDF
50 Laravel Tricks in 50 Minutes
PPT
Framework
PDF
The IoC Hydra
PDF
Advanced Django
KEY
Unit testing zend framework apps
Get AngularJS Started!
Drupal 8 Services
購物車程式架構簡介
Owl: The New Odoo UI Framework
Frontin like-a-backer
Integrating React.js with PHP projects
Doctrine 2
Contagion的Ruby/Rails投影片
 
TurboGears2 Pluggable Applications
Basic JSTL
Building a Pyramid: Symfony Testing Strategies
Php Unit With Zend Framework Zendcon09
Caching and Scaling WordPress using Fragment Caching
AngularJS Directives
AngularJS Basics with Example
50 Laravel Tricks in 50 Minutes
Framework
The IoC Hydra
Advanced Django
Unit testing zend framework apps
Ad

Similar to Using of TDD practices for Magento (20)

PPT
PHP Unit Testing
PPTX
Symfony 1, mi viejo amigo
ODP
From typing the test to testing the type
PPT
Test driven development_for_php
KEY
PHPUnit testing to Zend_Test
PDF
Curso Symfony - Clase 2
PPTX
Clean tests good tests
PDF
Curso Symfony - Clase 4
PDF
Introduction to Unit Testing with PHPUnit
PPTX
Growing up with Magento
PDF
PHPSpec BDD Framework
PPTX
Jasmine with JS-Test-Driver
ODP
Bring the fun back to java
PDF
Load Testing with PHP and RedLine13
KEY
Unit testing with zend framework PHPBenelux
PPT
Testing persistence in PHP with DbUnit
PDF
Unit testing with zend framework tek11
ODP
Best Practice Testing with Lime 2
PPT
Meet Magento DE 2016 - Kristof Ringleff - Growing up with Magento
PPTX
Continously delivering
PHP Unit Testing
Symfony 1, mi viejo amigo
From typing the test to testing the type
Test driven development_for_php
PHPUnit testing to Zend_Test
Curso Symfony - Clase 2
Clean tests good tests
Curso Symfony - Clase 4
Introduction to Unit Testing with PHPUnit
Growing up with Magento
PHPSpec BDD Framework
Jasmine with JS-Test-Driver
Bring the fun back to java
Load Testing with PHP and RedLine13
Unit testing with zend framework PHPBenelux
Testing persistence in PHP with DbUnit
Unit testing with zend framework tek11
Best Practice Testing with Lime 2
Meet Magento DE 2016 - Kristof Ringleff - Growing up with Magento
Continously delivering
Ad

Recently uploaded (20)

PPTX
Big Data Technologies - Introduction.pptx
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Encapsulation theory and applications.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
A Presentation on Artificial Intelligence
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Cloud computing and distributed systems.
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Approach and Philosophy of On baking technology
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Big Data Technologies - Introduction.pptx
Digital-Transformation-Roadmap-for-Companies.pptx
Unlocking AI with Model Context Protocol (MCP)
Spectral efficient network and resource selection model in 5G networks
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Review of recent advances in non-invasive hemoglobin estimation
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Network Security Unit 5.pdf for BCA BBA.
Encapsulation theory and applications.pdf
NewMind AI Weekly Chronicles - August'25 Week I
A Presentation on Artificial Intelligence
Machine learning based COVID-19 study performance prediction
Cloud computing and distributed systems.
Advanced methodologies resolving dimensionality complications for autism neur...
The Rise and Fall of 3GPP – Time for a Sabbatical?
Approach and Philosophy of On baking technology
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Understanding_Digital_Forensics_Presentation.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Bridging biosciences and deep learning for revolutionary discoveries: a compr...

Using of TDD practices for Magento

  • 1. Using of Test Driven DevelopmentPractices for MagentoIvan ChepurnyiMagento Trainer / Lead Developer
  • 2. Short OverviewMeet Magento NetherlandsWrite a testImaging how your feature should work and write a failing testWrite feature quickly for receiving passed testRefactor your code and run the test againPassRun the testsFailPassWrite the codeFailRun the tests
  • 3. Conventional DevelopmentMeet Magento NetherlandsYou need to write a full functionality for seeing the resultYou think that your code worksDebuggingWith every fixed issue you may produce a new oneEven if you write unit tests after implementation it doesn’t guarantee that you detect the defect.
  • 4. Test Driven DevelopmentMeet Magento NetherlandsYou don’t need to implement full functionality for seeing the resultYour colleagues can use your test as learning materialThe test proofs that your code works and can be verifiedSerious defects can be fixed on early state
  • 5. Defect CostsMeet Magento NetherlandsPercentage from project development hours< 1%20%> 40%Defect found at the coding stageDefect found during QA phaseDefect found after going live
  • 6. Type of TestsMeet Magento NetherlandsAutomated TestRegression TestLearning TestIntegration Test
  • 7. Meet Magento NetherlandsTest in IsolationMake test simpleTest erroneous situationsTest Doubles (Fake heavy resources you don’t depend on)Main Principles
  • 8. EcomDev_PHPUnitMeet Magento NetherlandsMaking possible isolation of your testEasy test data loading via Yaml fixturesData providers and expectations for reusable testsEasy way of testing configuration filesEasy way for Layouts & Controllers integration test
  • 9. Simple Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Model_Productextends EcomDev_PHPUnit_Test_Case{ /** * @test * @loadFixture * @dataProviderdataProvider */ public function priceCalculation($productId, $storeId) { $storeId = Mage::app()->getStore($storeId)->getId(); $product = Mage::getModel('catalog/product') ->setStoreId($storeId) ->load($productId); $expected = $this->expected('%s-%s', $productId, $storeId); $this->assertEquals($expected->getFinalPrice(), $product->getFinalPrice()); $this->assertEquals($expected->getPrice(), $product->getPrice()); }}Test Case Class
  • 10. Simple Test CaseMeet Magento Netherlandseav:   catalog_product:     - entity_id: 1       type_id: simple       sku: book          website_ids:          - usa_website          - canada_website          price: 12.99        status: 1  # Enabled        visibility: 4  # Visible in Catalog & Search        /websites:  # Set different prices per website         usa_website:           special_price: 9.99         german_website:            price: 9.99           special_price: 5.99 Yaml Fixture
  • 11. Simple Test CaseMeet Magento Netherlands1-2: # Product=Book Store=USAfinal_price: 9.99 price: 12.991-3: # Product=Book Store=Canadafinal_price: 12.99 price: 12.99Yaml ExpectationYaml Data Provider- - 1 - usa- - 1 - canada- - 1 - germany
  • 12. Event Dispatch CheckMeet Magento Netherlandsclass EcomDev_Example_Test_Model_Cms_Pageextends EcomDev_PHPUnit_Test_Case{ // … public function testAvailableStatuses() { Mage::getModel(‘cms/page’)->getAvailableStatuses(); $this->assertEventDispatched( ‘cms_page_get_available_statuses’ ); }}Test Case
  • 13. Test DoublesMeet Magento Netherlandsclass EcomDev_PHPUnit_Tes_Case_Controllerextends EcomDev_PHPUnit_Test_Case{ protected function registerCookieStub() { $cookie = $this->getModelMock('core/cookie', array('set', 'delete')); $cookie->expects($this->any()) ->method('set') ->will($this->returnCallback(array($this, 'setCookieCallback‘))); $cookie->expects($this->any()) ->method('delete‘) ->will($this->returnCallback(array($this, 'deleteCookieCallback‘))); $this->replaceByMock('singleton', 'core/cookie', $cookie); return $this; }}Test Case
  • 14. Config Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Config_Main extends EcomDev_PHPUnit_Test_Case_Config{ //…. public function testModuleVersion() { $this->assertModuleCodePool('local'); $this->assertModuleDepends(‘Mage_Catalog’); $this->assertModuleVersionGreaterThan(‘0.1.0'); }}Testing Module Nodes
  • 15. Config Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Config_Main extends EcomDev_PHPUnit_Test_Case_Config{ //…. public function testClassAliasDefinitions() { $this->assertModelAlias('catalog/product', 'Mage_Catalog_Model_Product'); $this->assertResourceModelAlias( 'catalog/product', ‘Mage_Catalog_Model_Resource_Eav_Mysql4_Product‘ ); $this->assertBlockAlias( 'catalog/product_list', 'Mage_Catalog_Block_Product_List‘ ); }}Testing Class Aliases
  • 16. Config Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Config_Main extends EcomDev_PHPUnit_Test_Case_Config{ //…. public function testEventObservers() { $this->assertEventObserverDefined( 'frontend', 'customer_login', 'catalog/product_compare_item', 'bindCustomerLogin' ); }}Testing Event Observer Definitions
  • 17. Controller Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Controller_Main extends EcomDev_PHPUnit_Test_Case_Controller{ public function testRequest() { $this->dispatch('cms'); $this->assertRequestDispatched(); $this->assertRequestNotForwarded(); $this->assertRequestRoute('cms/index/index'); $this->assertRequestRouteName('cms'); $this->assertRequestControllerName('index'); $this->assertRequestControllerModule('Mage_Cms'); $this->assertRequestActionName('index'); }}Testing Request
  • 18. Controller Test CaseMeet Magento Netherlandsclass EcomDev_Example_Test_Controller_Main extends EcomDev_PHPUnit_Test_Case_Controller{ public function testLayout() { $this->dispatch(''); $this->assertLayoutHandleLoaded('cms_index_index'); $this->assertLayoutBlockCreated('right'); $this->assertLayoutBlockRendered('content'); $this->assertLayoutBlockActionNotInvoked( 'footer_links', 'addLink', '', array('Custom Title') ); $this->assertLayoutBlockActionInvokedAtLeast( 'footer_links', 'addLink', 4, '‘ ); }}Testing Layouts
  • 19. What’s NextMeet Magento NetherlandsWrite automated tests for your moduleshttp://www.magentocommerce.com/magento-connect/Ecommerce%20Developers/extension/5717/ecomdev_phpunitKeep project healthy during its lifecycle with Continuous IntegrationRunning Daily BuildsRunning Unit Tests in 10 minutes after last commitHudson http://hudson-ci.orgphpUnderControlhttp://phpundercontrol.org/