SlideShare a Scribd company logo
1 of 89
Download to read offline
WRITING
TESTABLE
CODEWriting Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Vinai Kopp
Freelance Developer & Trainer
Tweet me @VinaiKopp
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
I want to get into testing
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
" WANT TO "
"I have to GET INTO TESTING"
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
CHOOSE A TOOL +
LEARN THE SYNTAX
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ PHPUnit
▸ PHPSpec
▸ Codeception
▸ nvm...
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
That wasn't so bad!
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Current status:
A metric ton of untested legacy code
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Start with writing tests for bugs
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
THIS IS HARD
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
This costs lots of time!
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
This is painful!
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
There has to be
a better way...!
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
<?php
/**
* @todo make more testable
*
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Things to keep in mind
to write TESTABLE CODE
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
KEEP CLASSES
SMALLWriting Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
A bad example:
Event Observer
(for Magento 1)
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
<?php
use Varien_Event_Observer as Event;
class Netzarbeiter_CustomerActivation_Model_Observer
{
// Check if the customer has been activated, if not, throw login error
public function customerLogin(Event $event) {...}
// Flag new accounts as such
public function customerSaveBefore(Event $event) {...}
// Send out emails
public function customerSaveAfter(Event $event) {...}
// Abort registration during checkout if default activation status is false
public function salesConvertQuoteAddressToOrder(Event $event) {...}
// Add customer activation option to the mass action block
public function adminhtmlBlockHtmlBefore(Event $event) {...}
// Add the customer_activated attribute to the customer grid collection
public function eavCollectionAbstractLoadBefore(Event $event) {...}
// Add customer_activated column to CSV and XML exports
public function coreBlockAbstractPrepareLayoutAfter(Event $event) {...}
// Remove the customer id from the customer/session, in effect causing a logout just in case
public function controllerActionPostdispatchCustomerAccountResetPasswordPost(Event $event) {...}
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
SMALLER?
HOW?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
First attempt:
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
WHAT DOES IT DO?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
1. Prevent inactive customer logins
2. Send notification emails
3. Add column to customer grid
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
split
Netzarbeiter_CustomerActivation_Model_Observer
into
..._Model_Observer_ProhibitInactiveLogins
..._Model_Observer_EmailNotifications
..._Model_Observer_AdminhtmlCustomerGrid
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
<?php
use Varien_Event_Observer as Event;
class Netzarbeiter_CustomerActivation_Model_Observer_ProhibitInactiveLogin
{
// Check if the customer has been activated, if not, throw login error
public function customerLogin(Event $event) {...}
// Abort registration during checkout if default activation status is false
public function salesConvertQuoteAddressToOrder(Event $event) {...}
// Remove the customer id from the customer/session, in effect causing a logout just in case
public function controllerActionPostdispatchCustomerAccountResetPasswordPost(Event $event) {...}
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
<?php
use Varien_Event_Observer as Event;
class Netzarbeiter_CustomerActivation_Model_Observer_EmailNotifications
{
// Flag new accounts as such
public function customerSaveBefore(Event $event) {...}
// Send out emails
public function customerSaveAfter(Event $event) {...}
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
<?php
use Varien_Event_Observer as Event;
class Netzarbeiter_CustomerActivation_Model_Observer_AdminhtmlCustomerGrid
{
// Add customer activation option to the mass action block
public function adminhtmlBlockHtmlBefore(Event $event) {...}
// Add the customer_activated attribute to the customer grid collection
public function eavCollectionAbstractLoadBefore(Event $event) {...}
// Add customer_activated column to CSV and XML exports
public function coreBlockAbstractPrepareLayoutAfter(Event $event) {...}
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Pretty rough...
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Okay first step
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
MINOR DIFFERENCE IN
TESTING EFFORT
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Second attempt:
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Look closer
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Dependencies:
Netzarbeiter_CustomerActivation_Helper_Data
Mage_Customer_Model_Customer
Mage_Customer_Model_Session
Mage_Customer_Model_Group
Mage_Customer_Helper_Address
Mage_Customer_Model_Resource_Customer_Collection
Mage_Core_Controller_Request_Http
Mage_Core_Controller_Response_Http
Mage_Core_Exception
Mage_Core_Model_Session
Mage_Core_Model_Store
Mage_Sales_Model_Quote_Address
Mage_Sales_Model_Quote
Mage_Eav_Model_Config
Mage_Eav_Model_Entity_Type
Mage_Adminhtml_Block_Widget_Grid_Massaction
Mage_Adminhtml_Block_Widget_Grid
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Business logic is hidden in Observer or Helper
Netzarbeiter_CustomerActivation_Model_Observer
Netzarbeiter_CustomerActivation_Helper_Data
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Observers link
Business logic
!
Magento
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Old Code:
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
public function customerLogin($observer)
{
$helper = Mage::helper('customeractivation');
if (!$helper->isModuleActive()) {
return;
}
if ($this->_isApiRequest()) {
return;
}
$customer = $observer->getEvent()->getCustomer();
$session = Mage::getSingleton('customer/session');
if (!$customer->getCustomerActivated()) {
$session->setCustomer(Mage::getModel('customer/customer'))
->setId(null)
->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
if ($this->_checkRequestRoute('customer', 'account', 'createpost')) {
$message = $helper->__('Please wait for your account to be activated');
$session->addSuccess($message);
} else {
Mage::throwException($helper->__('This account is not activated.'));
}
}
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
New Code:
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
public function customerLogin(Event $event)
{
if (! $this->isModuleActive()) {
return;
}
$this->getCustomerLoginSentry()->abortLoginIfNotActive(
$event->getData('customer')
);
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Details are hidden
▸ Delegation
▸ No magic getters
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
private static $sentry = 'customeractivation/customerLoginSentry';
/**
* @return Netzarbeiter_CustomerActivation_Model_CustomerLoginSentry
*/
private function getCustomerLoginSentry()
{
return isset($this->loginSentry) ?
$this->loginSentry :
Mage::getModel(self::$sentry);
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Dependencies can be injected
▸ Business logic moved into model
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Model with specific responsibility
class Netzarbeiter_CustomerActivation_Model_CustomerLoginSentry
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
public function abortLoginIfNotActive(Mage_Customer_Model_Customer $customer)
{
if (! $customer->getData('customer_activated') {
$this->getSession()->logout();
$this->getDisplay()->showLoginAbortedMessage();
}
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Business logic independent of entry point
▸ More type safety
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
private function getSession()
{
return isset($this->session) ?
$this->session :
Mage::getModel('customeractivation/session');
}
private function getDisplay()
{
return isset($this->display) ?
$this->display :
Mage::getModel('customeractivation/display');
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Injectable dependencies
▸ Business logic in specific models
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Need something done?
Need some information?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
"I don't care how it's done!"
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Delegate!
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
IDCDD
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
I Don't Care Driven Development
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
I Don't Care Driven Design
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
The result?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
CLASS EXPLOSION!
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
SMALL CLASSES
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
TrivialTO TEST
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
How far can delegation go?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Delegate until the next
delegator == delegatee
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
In the end
our class
is wrapping
a Magento class
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
In the end
our class
is wrapping
a Framework class
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
DECOUPLING FROM
THE FRAMEWORK
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
This is a Good Thing
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
ONE
FAQWHEN STARTING WITH TESTING
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
WHAT TO
TEST?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Better question:
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
WHY DOES
THE CLASS EXIST?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
WHY DOES
THE METHOD EXIST?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
RETURN A VALUE
OR
SIDE EFFECT
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
If a method
RETURNS A VALUE
only test for that
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
If a method
CAUSES A SIDE EFFECT
only test for that
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
SIDE EFFECTS?
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Side Effect #1:
Global State
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Filesystem
▸ Databases
▸ Global Functions + Variables
▸ Static Method Calls + Properties
▸ Forking
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Side Effect #2:
A method call on another object
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
if (! $customer->getData('customer_activated') {
$this->getSession()->logout();
$this->getDisplay()->showLoginAbortedMessage();
}
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
TESTING
RETURN VALUES
IS EASIER THAN
SIDE EFFECTS
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Avoid creating methods that do both:
side effect && return value
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
ALSO TEST FOR
EXCEPTIONS
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
Key Points
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Separation between
Hooks or Entry Points
and
Business Logic
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Split Business Logic into specific classes
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Use IDCDD to find where to separate
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Also separate code that
returns a value
from code that
causes a side effect
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Test if a class fulfills it's purpose
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Don't use magic methods
(No more calls to __call())
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Avoid method call chaining
(Don't return $this);
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
▸ Mainly for Magento 1.x:
Make dependencies injectable for testing
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
...and have fun testing!
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
(tell you me comment)
(ask? you me question)
(thank you)
Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp

More Related Content

Viewers also liked

Product Search in Magento 2
Product Search in Magento 2Product Search in Magento 2
Product Search in Magento 2Sonja Riesterer
 
Microservices and elastic resource pools with Amazon EC2 Container Service
Microservices and elastic resource pools with Amazon EC2 Container ServiceMicroservices and elastic resource pools with Amazon EC2 Container Service
Microservices and elastic resource pools with Amazon EC2 Container ServiceBoyan Dimitrov
 
Mage Titans USA 2016 Magento/Facebook/RabbitMQ
Mage Titans USA 2016 Magento/Facebook/RabbitMQMage Titans USA 2016 Magento/Facebook/RabbitMQ
Mage Titans USA 2016 Magento/Facebook/RabbitMQVrann Tulika
 
Θεωρία Πανελληνίων ΑΟΘ
Θεωρία Πανελληνίων ΑΟΘΘεωρία Πανελληνίων ΑΟΘ
Θεωρία Πανελληνίων ΑΟΘGeorgia Kazakou
 
Reasons Why Employees Resist Change (Infographic)
Reasons Why Employees Resist Change (Infographic)Reasons Why Employees Resist Change (Infographic)
Reasons Why Employees Resist Change (Infographic)Catherine Adenle
 
Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015
Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015
Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015Joshua Warren
 
How to Make Great Software Estimates
How to Make Great Software EstimatesHow to Make Great Software Estimates
How to Make Great Software EstimatesGreg Thomas
 
Mage Titans USA 2016 - Eugene Tulika - Integrations with Magento, end to end...
Mage Titans USA 2016 - Eugene Tulika -  Integrations with Magento, end to end...Mage Titans USA 2016 - Eugene Tulika -  Integrations with Magento, end to end...
Mage Titans USA 2016 - Eugene Tulika - Integrations with Magento, end to end...Stacey Whitney
 
Writing Smarter Applications with Machine Learning
Writing Smarter Applications with Machine LearningWriting Smarter Applications with Machine Learning
Writing Smarter Applications with Machine LearningAnoop Thomas Mathew
 

Viewers also liked (12)

Sitokinesis
SitokinesisSitokinesis
Sitokinesis
 
Product Search in Magento 2
Product Search in Magento 2Product Search in Magento 2
Product Search in Magento 2
 
Music types
Music typesMusic types
Music types
 
Microservices and elastic resource pools with Amazon EC2 Container Service
Microservices and elastic resource pools with Amazon EC2 Container ServiceMicroservices and elastic resource pools with Amazon EC2 Container Service
Microservices and elastic resource pools with Amazon EC2 Container Service
 
Mage Titans USA 2016 Magento/Facebook/RabbitMQ
Mage Titans USA 2016 Magento/Facebook/RabbitMQMage Titans USA 2016 Magento/Facebook/RabbitMQ
Mage Titans USA 2016 Magento/Facebook/RabbitMQ
 
Θεωρία Πανελληνίων ΑΟΘ
Θεωρία Πανελληνίων ΑΟΘΘεωρία Πανελληνίων ΑΟΘ
Θεωρία Πανελληνίων ΑΟΘ
 
Reasons Why Employees Resist Change (Infographic)
Reasons Why Employees Resist Change (Infographic)Reasons Why Employees Resist Change (Infographic)
Reasons Why Employees Resist Change (Infographic)
 
Effective Ways to Overcome Resistance to Change
Effective Ways to Overcome  Resistance to Change Effective Ways to Overcome  Resistance to Change
Effective Ways to Overcome Resistance to Change
 
Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015
Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015
Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015
 
How to Make Great Software Estimates
How to Make Great Software EstimatesHow to Make Great Software Estimates
How to Make Great Software Estimates
 
Mage Titans USA 2016 - Eugene Tulika - Integrations with Magento, end to end...
Mage Titans USA 2016 - Eugene Tulika -  Integrations with Magento, end to end...Mage Titans USA 2016 - Eugene Tulika -  Integrations with Magento, end to end...
Mage Titans USA 2016 - Eugene Tulika - Integrations with Magento, end to end...
 
Writing Smarter Applications with Machine Learning
Writing Smarter Applications with Machine LearningWriting Smarter Applications with Machine Learning
Writing Smarter Applications with Machine Learning
 

Similar to Writing testable Code (MageTitans Mini 2016)

Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)vinaikopp
 
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
Writing Testable Code (for Magento 1 and 2)  2016 RomainaWriting Testable Code (for Magento 1 and 2)  2016 Romaina
Writing Testable Code (for Magento 1 and 2) 2016 Romainavinaikopp
 
Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)vinaikopp
 
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)vinaikopp
 
Vinai Kopp - How i develop M2 modules
Vinai Kopp - How i develop M2 modules Vinai Kopp - How i develop M2 modules
Vinai Kopp - How i develop M2 modules Meet Magento Italy
 
Testing Magento 2
Testing Magento 2Testing Magento 2
Testing Magento 2vinaikopp
 
A true story about Magento best practices
A true story about Magento best practicesA true story about Magento best practices
A true story about Magento best practicesAlessandro Ronchi
 
SOS UiComponents
SOS UiComponentsSOS UiComponents
SOS UiComponentsvinaikopp
 
Magento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata IntroMagento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata Introvinaikopp
 
Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018vinaikopp
 
Magento 2 TDD Code Kata
Magento 2 TDD Code KataMagento 2 TDD Code Kata
Magento 2 TDD Code Katavinaikopp
 
Architecture in-the-small-slides
Architecture in-the-small-slidesArchitecture in-the-small-slides
Architecture in-the-small-slidesvinaikopp
 
8 Secrets To Fill Your Business In 60 Days
8 Secrets To Fill Your Business In 60 Days8 Secrets To Fill Your Business In 60 Days
8 Secrets To Fill Your Business In 60 DaysDonna Gunter
 
Secure development environment @ Meet Magento Croatia 2017
Secure development environment @ Meet Magento Croatia 2017Secure development environment @ Meet Magento Croatia 2017
Secure development environment @ Meet Magento Croatia 2017Anna Völkl
 
GU_SAP S4 HANA CLOUD_How to Set Up the Email Notification for Flexible Workfl...
GU_SAP S4 HANA CLOUD_How to Set Up the Email Notification for Flexible Workfl...GU_SAP S4 HANA CLOUD_How to Set Up the Email Notification for Flexible Workfl...
GU_SAP S4 HANA CLOUD_How to Set Up the Email Notification for Flexible Workfl...MICKAEL QUESNOT
 
Extension Submission to Marketplace
Extension Submission to MarketplaceExtension Submission to Marketplace
Extension Submission to MarketplaceWagento Kangiya
 
Vinai Kopp - FPC Hole punching in Magento 2
Vinai Kopp - FPC Hole punching in Magento 2Vinai Kopp - FPC Hole punching in Magento 2
Vinai Kopp - FPC Hole punching in Magento 2Meet Magento Italy
 
Secure input and output handling - Meet Magento Romania 2016
Secure input and output handling - Meet Magento Romania 2016Secure input and output handling - Meet Magento Romania 2016
Secure input and output handling - Meet Magento Romania 2016Anna Völkl
 
Analytics - marketing hell week 2015 -- tammy camp
Analytics  - marketing hell week 2015 -- tammy campAnalytics  - marketing hell week 2015 -- tammy camp
Analytics - marketing hell week 2015 -- tammy camp500 Startups
 

Similar to Writing testable Code (MageTitans Mini 2016) (20)

Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)Writing Testable Code (for Magento 1 and 2)
Writing Testable Code (for Magento 1 and 2)
 
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
Writing Testable Code (for Magento 1 and 2)  2016 RomainaWriting Testable Code (for Magento 1 and 2)  2016 Romaina
Writing Testable Code (for Magento 1 and 2) 2016 Romaina
 
Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)Getting your hands dirty testing Magento 2 (at MageTitansIT)
Getting your hands dirty testing Magento 2 (at MageTitansIT)
 
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)Getting your Hands Dirty Testing Magento 2 (at London Meetup)
Getting your Hands Dirty Testing Magento 2 (at London Meetup)
 
Vinai Kopp - How i develop M2 modules
Vinai Kopp - How i develop M2 modules Vinai Kopp - How i develop M2 modules
Vinai Kopp - How i develop M2 modules
 
Testing Magento 2
Testing Magento 2Testing Magento 2
Testing Magento 2
 
A true story about Magento best practices
A true story about Magento best practicesA true story about Magento best practices
A true story about Magento best practices
 
SOS UiComponents
SOS UiComponentsSOS UiComponents
SOS UiComponents
 
Magento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata IntroMagento 2 TDD Code Kata Intro
Magento 2 TDD Code Kata Intro
 
Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018Becoming Certified - MageTitansMCR 2018
Becoming Certified - MageTitansMCR 2018
 
Magento 2 TDD Code Kata
Magento 2 TDD Code KataMagento 2 TDD Code Kata
Magento 2 TDD Code Kata
 
Architecture in-the-small-slides
Architecture in-the-small-slidesArchitecture in-the-small-slides
Architecture in-the-small-slides
 
SHOPKEEPER APP
SHOPKEEPER APPSHOPKEEPER APP
SHOPKEEPER APP
 
8 Secrets To Fill Your Business In 60 Days
8 Secrets To Fill Your Business In 60 Days8 Secrets To Fill Your Business In 60 Days
8 Secrets To Fill Your Business In 60 Days
 
Secure development environment @ Meet Magento Croatia 2017
Secure development environment @ Meet Magento Croatia 2017Secure development environment @ Meet Magento Croatia 2017
Secure development environment @ Meet Magento Croatia 2017
 
GU_SAP S4 HANA CLOUD_How to Set Up the Email Notification for Flexible Workfl...
GU_SAP S4 HANA CLOUD_How to Set Up the Email Notification for Flexible Workfl...GU_SAP S4 HANA CLOUD_How to Set Up the Email Notification for Flexible Workfl...
GU_SAP S4 HANA CLOUD_How to Set Up the Email Notification for Flexible Workfl...
 
Extension Submission to Marketplace
Extension Submission to MarketplaceExtension Submission to Marketplace
Extension Submission to Marketplace
 
Vinai Kopp - FPC Hole punching in Magento 2
Vinai Kopp - FPC Hole punching in Magento 2Vinai Kopp - FPC Hole punching in Magento 2
Vinai Kopp - FPC Hole punching in Magento 2
 
Secure input and output handling - Meet Magento Romania 2016
Secure input and output handling - Meet Magento Romania 2016Secure input and output handling - Meet Magento Romania 2016
Secure input and output handling - Meet Magento Romania 2016
 
Analytics - marketing hell week 2015 -- tammy camp
Analytics  - marketing hell week 2015 -- tammy campAnalytics  - marketing hell week 2015 -- tammy camp
Analytics - marketing hell week 2015 -- tammy camp
 

More from vinaikopp

Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023vinaikopp
 
Hyvä: Compatibility Modules
Hyvä: Compatibility ModulesHyvä: Compatibility Modules
Hyvä: Compatibility Modulesvinaikopp
 
Hyvä from a developer perspective
Hyvä from a developer perspectiveHyvä from a developer perspective
Hyvä from a developer perspectivevinaikopp
 
Property Based Testing in PHP
Property Based Testing in PHPProperty Based Testing in PHP
Property Based Testing in PHPvinaikopp
 
Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019vinaikopp
 
ClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNvinaikopp
 
ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017vinaikopp
 
Lizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17deLizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17devinaikopp
 
Stories from the other side
Stories from the other sideStories from the other side
Stories from the other sidevinaikopp
 
Modern Module Architecture
Modern Module ArchitectureModern Module Architecture
Modern Module Architecturevinaikopp
 
The beautiful Magento module - MageTitans 2014
The beautiful Magento module - MageTitans 2014The beautiful Magento module - MageTitans 2014
The beautiful Magento module - MageTitans 2014vinaikopp
 

More from vinaikopp (11)

Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023Building Mage-OS - MageTitans 2023
Building Mage-OS - MageTitans 2023
 
Hyvä: Compatibility Modules
Hyvä: Compatibility ModulesHyvä: Compatibility Modules
Hyvä: Compatibility Modules
 
Hyvä from a developer perspective
Hyvä from a developer perspectiveHyvä from a developer perspective
Hyvä from a developer perspective
 
Property Based Testing in PHP
Property Based Testing in PHPProperty Based Testing in PHP
Property Based Testing in PHP
 
Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019Property based testing - MageTestFest 2019
Property based testing - MageTestFest 2019
 
ClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRNClojureScript in Magento 2 - PHPUGMRN
ClojureScript in Magento 2 - PHPUGMRN
 
ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017ClojureScript in Magento 2 - MageTitansMCR 2017
ClojureScript in Magento 2 - MageTitansMCR 2017
 
Lizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17deLizards & Pumpkins Catalog Replacement at mm17de
Lizards & Pumpkins Catalog Replacement at mm17de
 
Stories from the other side
Stories from the other sideStories from the other side
Stories from the other side
 
Modern Module Architecture
Modern Module ArchitectureModern Module Architecture
Modern Module Architecture
 
The beautiful Magento module - MageTitans 2014
The beautiful Magento module - MageTitans 2014The beautiful Magento module - MageTitans 2014
The beautiful Magento module - MageTitans 2014
 

Recently uploaded

Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 

Recently uploaded (20)

Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 

Writing testable Code (MageTitans Mini 2016)

  • 1. WRITING TESTABLE CODEWriting Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 2. Vinai Kopp Freelance Developer & Trainer Tweet me @VinaiKopp Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 3. I want to get into testing Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 4. " WANT TO " "I have to GET INTO TESTING" Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 5. CHOOSE A TOOL + LEARN THE SYNTAX Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 6. ▸ PHPUnit ▸ PHPSpec ▸ Codeception ▸ nvm... Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 7. That wasn't so bad! Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 8. Current status: A metric ton of untested legacy code Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 9. Start with writing tests for bugs Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 10. THIS IS HARD Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 11. This costs lots of time! Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 12. This is painful! Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 13. There has to be a better way...! Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 14. <?php /** * @todo make more testable * Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 15. Things to keep in mind to write TESTABLE CODE Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 16. KEEP CLASSES SMALLWriting Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 17. A bad example: Event Observer (for Magento 1) Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 18. <?php use Varien_Event_Observer as Event; class Netzarbeiter_CustomerActivation_Model_Observer { // Check if the customer has been activated, if not, throw login error public function customerLogin(Event $event) {...} // Flag new accounts as such public function customerSaveBefore(Event $event) {...} // Send out emails public function customerSaveAfter(Event $event) {...} // Abort registration during checkout if default activation status is false public function salesConvertQuoteAddressToOrder(Event $event) {...} // Add customer activation option to the mass action block public function adminhtmlBlockHtmlBefore(Event $event) {...} // Add the customer_activated attribute to the customer grid collection public function eavCollectionAbstractLoadBefore(Event $event) {...} // Add customer_activated column to CSV and XML exports public function coreBlockAbstractPrepareLayoutAfter(Event $event) {...} // Remove the customer id from the customer/session, in effect causing a logout just in case public function controllerActionPostdispatchCustomerAccountResetPasswordPost(Event $event) {...} } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 19. SMALLER? HOW? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 20. First attempt: Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 21. WHAT DOES IT DO? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 22. 1. Prevent inactive customer logins 2. Send notification emails 3. Add column to customer grid Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 24. <?php use Varien_Event_Observer as Event; class Netzarbeiter_CustomerActivation_Model_Observer_ProhibitInactiveLogin { // Check if the customer has been activated, if not, throw login error public function customerLogin(Event $event) {...} // Abort registration during checkout if default activation status is false public function salesConvertQuoteAddressToOrder(Event $event) {...} // Remove the customer id from the customer/session, in effect causing a logout just in case public function controllerActionPostdispatchCustomerAccountResetPasswordPost(Event $event) {...} } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 25. <?php use Varien_Event_Observer as Event; class Netzarbeiter_CustomerActivation_Model_Observer_EmailNotifications { // Flag new accounts as such public function customerSaveBefore(Event $event) {...} // Send out emails public function customerSaveAfter(Event $event) {...} } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 26. <?php use Varien_Event_Observer as Event; class Netzarbeiter_CustomerActivation_Model_Observer_AdminhtmlCustomerGrid { // Add customer activation option to the mass action block public function adminhtmlBlockHtmlBefore(Event $event) {...} // Add the customer_activated attribute to the customer grid collection public function eavCollectionAbstractLoadBefore(Event $event) {...} // Add customer_activated column to CSV and XML exports public function coreBlockAbstractPrepareLayoutAfter(Event $event) {...} } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 27. Pretty rough... Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 28. Okay first step Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 29. MINOR DIFFERENCE IN TESTING EFFORT Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 30. Second attempt: Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 31. Look closer Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 33. Business logic is hidden in Observer or Helper Netzarbeiter_CustomerActivation_Model_Observer Netzarbeiter_CustomerActivation_Helper_Data Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 34. Observers link Business logic ! Magento Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 35. Old Code: Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 36. public function customerLogin($observer) { $helper = Mage::helper('customeractivation'); if (!$helper->isModuleActive()) { return; } if ($this->_isApiRequest()) { return; } $customer = $observer->getEvent()->getCustomer(); $session = Mage::getSingleton('customer/session'); if (!$customer->getCustomerActivated()) { $session->setCustomer(Mage::getModel('customer/customer')) ->setId(null) ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID); if ($this->_checkRequestRoute('customer', 'account', 'createpost')) { $message = $helper->__('Please wait for your account to be activated'); $session->addSuccess($message); } else { Mage::throwException($helper->__('This account is not activated.')); } } } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 37. New Code: Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 38. public function customerLogin(Event $event) { if (! $this->isModuleActive()) { return; } $this->getCustomerLoginSentry()->abortLoginIfNotActive( $event->getData('customer') ); } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 39. ▸ Details are hidden ▸ Delegation ▸ No magic getters Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 40. private static $sentry = 'customeractivation/customerLoginSentry'; /** * @return Netzarbeiter_CustomerActivation_Model_CustomerLoginSentry */ private function getCustomerLoginSentry() { return isset($this->loginSentry) ? $this->loginSentry : Mage::getModel(self::$sentry); } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 41. ▸ Dependencies can be injected ▸ Business logic moved into model Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 42. Model with specific responsibility class Netzarbeiter_CustomerActivation_Model_CustomerLoginSentry Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 43. public function abortLoginIfNotActive(Mage_Customer_Model_Customer $customer) { if (! $customer->getData('customer_activated') { $this->getSession()->logout(); $this->getDisplay()->showLoginAbortedMessage(); } } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 44. ▸ Business logic independent of entry point ▸ More type safety Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 45. private function getSession() { return isset($this->session) ? $this->session : Mage::getModel('customeractivation/session'); } private function getDisplay() { return isset($this->display) ? $this->display : Mage::getModel('customeractivation/display'); } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 46. ▸ Injectable dependencies ▸ Business logic in specific models Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 47. Need something done? Need some information? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 48. "I don't care how it's done!" Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 49. Delegate! Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 50. IDCDD Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 51. I Don't Care Driven Development Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 52. I Don't Care Driven Design Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 53. The result? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 54. CLASS EXPLOSION! Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 55. SMALL CLASSES Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 56. TrivialTO TEST Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 57. How far can delegation go? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 58. Delegate until the next delegator == delegatee Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 59. In the end our class is wrapping a Magento class Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 60. In the end our class is wrapping a Framework class Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 61. DECOUPLING FROM THE FRAMEWORK Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 62. This is a Good Thing Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 63. ONE FAQWHEN STARTING WITH TESTING Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 64. WHAT TO TEST? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 65. Better question: Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 66. WHY DOES THE CLASS EXIST? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 67. WHY DOES THE METHOD EXIST? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 68. RETURN A VALUE OR SIDE EFFECT Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 69. If a method RETURNS A VALUE only test for that Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 70. If a method CAUSES A SIDE EFFECT only test for that Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 71. SIDE EFFECTS? Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 72. Side Effect #1: Global State Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 73. ▸ Filesystem ▸ Databases ▸ Global Functions + Variables ▸ Static Method Calls + Properties ▸ Forking Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 74. Side Effect #2: A method call on another object Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 75. if (! $customer->getData('customer_activated') { $this->getSession()->logout(); $this->getDisplay()->showLoginAbortedMessage(); } Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 76. TESTING RETURN VALUES IS EASIER THAN SIDE EFFECTS Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 77. Avoid creating methods that do both: side effect && return value Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 78. ALSO TEST FOR EXCEPTIONS Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 79. Key Points Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 80. ▸ Separation between Hooks or Entry Points and Business Logic Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 81. ▸ Split Business Logic into specific classes Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 82. ▸ Use IDCDD to find where to separate Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 83. ▸ Also separate code that returns a value from code that causes a side effect Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 84. ▸ Test if a class fulfills it's purpose Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 85. ▸ Don't use magic methods (No more calls to __call()) Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 86. ▸ Avoid method call chaining (Don't return $this); Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 87. ▸ Mainly for Magento 1.x: Make dependencies injectable for testing Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 88. ...and have fun testing! Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp
  • 89. (tell you me comment) (ask? you me question) (thank you) Writing Testable Code - MageTitans Mini, 5th May 2016 - ! - contact@vinaikopp.com - twitter://@VinaiKopp