Slide 1

Slide 1 text

TDD & CONTINUOUS INTEGRATION WITH MAGENTO Manuele Menozzi Senior PHP Developer @ Proud & member First Magento extension written in the 2009 Email: / Twitter: Webgriffe® GrUSP PUG MoRe [email protected] @mmenozzi

Slide 2

Slide 2 text

TEST DRIVEN DEVELOPMENT The repetition of a very short development cycle

Slide 3

Slide 3 text

TEST DRIVEN DEVELOPMENT BENEFITS You can write small feature's subsets (don't worry about all the complexity) All features are tested You reduce bugs and regressions rate Your code stays clean Your code is documented And last but not least, you're more confident in making changes!

Slide 4

Slide 4 text

TEST DRIVEN DEVELOPMENT IN PHP PHPUnit github.com/sebastianbergmann/phpunit/

Slide 5

Slide 5 text

UNIT TESTS WITH MAGENTO Magento => Hardcoded dependencies => Testing hell c l a s s V e n d o r _ M o d u l e _ M o d e l _ S o m e t h i n g e x t e n d s M a g e _ C o r e _ M o d e l _ A b s t r a c t { p u b l i c f u n c t i o n d o S o m e t h i n g W i t h P r o d u c t ( $ p r o d u c t I d ) { $ p r o d u c t = M a g e : : g e t M o d e l ( ' c a t a l o g / p r o d u c t ' ) - > l o a d ( $ p r o d u c t I d ) ; / / d o s o m e t h i n g w i t h $ p r o d u c t } }

Slide 6

Slide 6 text

UNIT TESTS WITH MAGENTO We have to refactor, for example with dependency injection… c l a s s V e n d o r _ M o d u l e _ M o d e l _ S o m e t h i n g e x t e n d s M a g e _ C o r e _ M o d e l _ A b s t r a c t { p r o t e c t e d $ p r o d u c t M o d e l ; p u b l i c f u n c t i o n s e t P r o d u c t M o d e l ( M a g e _ C a t a l o g _ M o d e l _ P r o d u c t $ p r o d u c t M o d e l ) { $ t h i s - > p r o d u c t M o d e l = $ p r o d u c t M o d e l ; } p u b l i c f u n c t i o n d o S o m e t h i n g W i t h P r o d u c t ( $ p r o d u c t I d ) { $ p r o d u c t = $ t h i s - > p r o d u c t M o d e l - > l o a d ( $ p r o d u c t I d ) ; / / d o s o m e t h i n g w i t h $ p r o d u c t } }

Slide 7

Slide 7 text

UNIT TESTS WITH MAGENTO … so we can test it with something like this: c l a s s V e n d o r _ M o d u l e _ T e s t s _ U n i t _ S o m e t h i n g T e s t e x t e n d s \ P H P U n i t _ F r a m e w o r k _ T e s t C a s e { p u b l i c f u n c t i o n t e s t D o S o m e t h i n g W i t h P r o d u c t ( ) { $ p r o d u c t M o d e l M o c k = $ t h i s - > g e t M o c k ( ' M a g e _ C a t a l o g _ M o d e l _ P r o d u c t ' ) ; $ p r o d u c t M o d e l M o c k - > e x p e c t s ( $ t h i s - > o n c e ( ) ) - > m e t h o d ( ' l o a d ' ) - > w i t h ( 1 ) - > w i l l ( $ t h i s - > r e t u r n V a l u e ( n e w M a g e _ C a t a l o g _ M o d e l _ P r o d u c t ( ) ) ) ; $ s o m e t h i n g M o d e l = n e w V e n d o r _ M o d u l e _ M o d e l _ S o m e t h i n g ( ) ; $ s o m e t h i n g M o d e l - > s e t P r o d u c t M o d e l ( $ p r o d u c t M o d e l M o c k ) ; $ s o m e t h i n g M o d e l - > d o S o m e t h i n g W i t h P r o d u c t ( 1 ) ; / / a s s e r t t h a t s o m e t h i n g h a s b e e n d o n e } }

Slide 8

Slide 8 text

INTEGRATION & FUNCTIONAL TESTS WITH MAGENTO Magento Test Automation Framework Backport of Magento 2 Tests Mage-Test MageSpec EcomDev_PHPUnit github.com/magento/taf github.com/techdivision/TechDivision_MagentoUnitTesting github.com/MageTest/Mage-Test github.com/MageHack/MageSpec github.com/EcomDev/EcomDev_PHPUnit

Slide 9

Slide 9 text

ECOMDEV_PHPUNIT Magento extension Doesn't change core files Separate database connection is used for tests Different levels of test integration

Slide 10

Slide 10 text

ECOMDEV_PHPUNIT Enable an extension for testing < ! - - a p p / c o d e / l o c a l / V e n d o r / M o d u l e / e t c / c o n f i g . x m l - - > < p h p u n i t > < s u i t e > < m o d u l e s > < V e n d o r _ M o d u l e / > < / m o d u l e s > < / s u i t e > < / p h p u n i t >

Slide 11

Slide 11 text

ECOMDEV_PHPUNIT DIFFERENT LEVELS OF TEST INTEGRATION EcomDev_PHPUnit_Test_Case is for testing models, blocks and helpers EcomDev_PHPUnit_Test_Case_Config is for testing your module configuration EcomDev_PHPUnit_Test_Case_Controller is for testing your controller actions and layout rendering process

Slide 12

Slide 12 text

ECOMDEV_PHPUNIT Fixtures support (YAML files, database purge) Expectations support (YAML files) Data providers support (YAML files) Indexing control (@doNotIndex & @doNotIndexAll) Useful test doubles getModelMock(), getResourceModelMock(), getBlockMock(), getHelperMock(), replaceByMock(), … Useful assertions assertEventDispatched(), assertEventDispatchedExactly(), assertEventDispatchedAtLeast(), …

Slide 13

Slide 13 text

ECOMDEV_PHPUNIT CONFIGURATION TESTING Many useful configuration assertions: Class Alias Assertions assertBlockAlias(), assertModelAlias(), assertHelperAlias(), … Module Assertions assertModuleCodePool(), assertModuleDepends(), assertModuleVersion(), … Layout Assertions assertLayoutFileDefined(), assertLayoutFileExists(), assertLayoutFileExistsInTheme(), … Event Observer Assertions assertEventObserverDefined(), assertEventObserverNotDefined(), … Config Node Assertions assertConfigNodeHasChild(), assertConfigNodeHasChildren(), assertConfigNodeContainsValue(), …

Slide 14

Slide 14 text

ECOMDEV_PHPUNIT CONTROLLER TESTING Dispatch of controller actions $this->dispatch('customer/account/create'); Response object handling & assertions getSentHeaders(), getOutputBody(), assertResponseHttpCode(), assertRedirect(), … Layout assertions assertLayoutLoaded(), assertLayoutBlockCreated(), assertLayoutBlockTypeOf(), assertLayoutBlockParentEquals(), assertLayoutBlockAfter(), … Routing assertions assertRequestDispatched(), assertRequestRoute(), assertRequestControllerName(), …

Slide 15

Slide 15 text

CONTINUOUS INTEGRATION What is it? Continuous integration (CI) is the practice, in software engineering, of merging all developer working copies with a shared mainline several times a day.

Slide 16

Slide 16 text

CONTINUOUS INTEGRATION Why do it? Reduce risk Reduce costs Confidence Tested builds Reduce repetitive tasks Quality assurance

Slide 17

Slide 17 text

CONTINUOUS INTEGRATION Requirements Source code repository Automated self-testing build Every commit triggers a build [ Automated deploy after every successful build ]

Slide 18

Slide 18 text

MAGENTO MODULE CONTINUOUS INTEGRATION We have to: Download and install a specific version of Magento Install the module Install EcomDev_PHPUnit Run tests Repeat the above steps for other Magento versions

Slide 19

Slide 19 text

MAGENTO MODULE CONTINUOUS INTEGRATION We can do it with MageCI by EcomDev ( ): github.com/EcomDev/MageCI $ m a g e - c i i n s t a l l $ m a g e _ d i r $ m a g e _ v e r s i o n $ d b n a m e - u $ d b u s e r - p $ d b p a s s \ - o - c - t - r h t t p : / / m a g e - c i . e c o m d e v . o r g $ m a g e - c i i n s t a l l - m o d u l e $ m a g e _ d i r . $ m a g e - c i i n s t a l l - m o d u l e $ m a g e _ d i r \ h t t p s : / / g i t h u b . c o m / E c o m D e v / E c o m D e v _ P H P U n i t . g i t $ m a g e - c i p h p u n i t $ m a g e _ d i r

Slide 20

Slide 20 text

MAGENTO MODULE CONTINUOUS INTEGRATION JENKINS EXAMPLE jenkins-ci.org Put previous commands in a bash script or an ANT build Multi-configuration job on Jenkins User-defined axis -> mage_version = 1.5.1.0, 1.6.2.0, 1.7.0.2, [...]

Slide 21

Slide 21 text

MAGENTO MODULE CONTINUOUS INTEGRATION JENKINS EXAMPLE

Slide 22

Slide 22 text

?