Run Unit Testing in Magento 2

Run Unit Testing in Magento 2

Unit Testing

Unit Testing is a method for Software Testing by which individual units (function, method in a class), their associated data, usage and operations are tested to determine if these are working as per designed.

 

As this is based on individual unit testing, there is no coupling among units and that is very easy to test because it avoids complications.

 

Benefits Of Unit Testing:

 

Easy to Debug:

Unit testing finds problem early because it isolates each part of the program and shows that individual part are correct. This includes debugging the program logic and flaws or missing parts of the specification for the unit.

 

Quality of Code:

As unit testing identifies the bugs at program level, it improves the quality of code. It restricts programmer to follow the standard to fix the bugs.

 

Make Program Easy to Change/Upgrade:

Unit testing makes easy for programmer to refactor/upgrade the code later because it makes a high cohesion among programs and make sure the module works correctly even after changes or upgradation.

 

Design Accuracy:

Unit testing restricts programmer to follow the code standards and focus on specifications for the unit. To fulfil the specifications of a unit, unit testing forces programmer to think about design too which makes the design more accurate.

 

Reduce Costs:

Unit testing helps to find and fix the bugs at early stage which reduces the cost and saves time to debug the modules at later stage. It reduces the complexity during System Testing and make everything smooth in development.

 

Implementing Unit Testing In Magento 2

Magento 2 has been launched with PHPUnit pre-installed, an automated testing framework for PHP. It has been included as dependency in Magento 2. So, here is the custom module which will help you to understand about basic implementation of Unit Testing. You will see the custom module to check a given string should be alphabetical.

Following are the steps:

Create And Register A New Custom Module

To create a custom module, very first step is to create a file, module.xml in folder, <Magento Root Folder>/app/code/<Vendor Name>/<Module Name>/etc/ folder. Let’s take the path -

/app/code/Bizspice/UnitTesting/etc/module.xml

and paste the following code into this file:

 

<?xml version="1.0" ?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">             <module name="Bizspice_UnitTesting" setup_version="1.0">   </module> </config>

 

Now, create a file registration.php in /app/code/Bizspice/UnitTesting/ folder with the following code:

 

<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE,      'Bizspice_UnitTesting',      __DIR__  ); 

 

Create Model File

Create Alphabet.php under /app/code/Bizspice/UnitTesting/Model folder with the following code:

 

<?php  namespace Bizspice\UnitTesting\Model;    class Alphabet {      /**       * this function will accept and return the string       *        * @param string str       * @return string       */      public function getText($str) {          if(preg_match("/^[a-zA-Z][a-zA-Z ]*$/", $str)){              return $str;           }else{  return false;      }  } 

 

Here, you can see getText() function which checks the string and checks if it contains only alphabets or not.

 

Create Test File:

Now, create a file to test getText() function. Create AlphabetTest.php under  /app/code/Bizspice/UnitTesting/Test/Unit/Model/ folder with the following code:

 

<?php  namespace Bizspice\UnitTesting\Test\Unit\Model;    class AlphabetTest extends  \PHPUnit\Framework\TestCase {        protected $_objectManager;      protected $_desiredResult;      protected $_actualResult;      protected $_alphabet;      protected $_text;        /**        * used to set the values to variables or objects.       *        * @return void        */       public function setUp() {          $this->_objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);          $this->_alphabet = $this->_objectManager->getObject("Bizspice\UnitTesting\Model\Alphabet");       }      /**       * this function will check if string is having alphabets only      */      public function testGetText() {           $this->_actualResult = $this->_alphabet->getText("This is my testing string");           $this->_desiredResult = "This is my testing string";           $this->assertEquals($this->_desiredResult, $this->_actualResult);       }  } 

 

All tests files must be named with Test.php as suffix because it has to be mentioned in phpunit.xml file. You will see it soon below.

Also, the path of the test files must be mirror of files to be tested. For instance, we have created /app/code/Bizspice/UnitTesting/Model/Alphabet.php so test file must be located at /app/code/Bizspice/UnitTesting/Test/Unit/Model/AlphabetTest.php.

 

Enable Module

To test a function/method, its corresponding module must be enabled. So, open the terminal, go to your Magento directory and run the following commands to enable the module:

 

rm -rf pub/static/* var/* generated/*;chmod 0777 var/ pub/ generated/;chmod 0777 -R var/ generated/ pub/;php bin/magento setup:upgrade php bin/magento setup:di:compile 
php bin/magento setup:static-content:deploy -fphp bin/magento indexer:reindex
php bin/magento cache:clean
php bin/magento cache:flush

 

phpunit.xml

After enabling the module, now it has to be tested. Actually, Magento 2 has made testing very easy and <root folder>/dev/tests/unit/phpunit.xml.distfile has to be managed for this.

Rename this file to phpunit.xml and open this file. Go to <testsuite name="Magento Unit Tests"> tag:

 

Add the following line into testsuite tag:

 

<directory suffix="Test.php">../../../app/code/Bizspice/UnitTesting/Test/Unit</directory>

 

As attribute suffix denotes that fetch all files having suffix Test.php and existing under /app/code/Bizspice/UnitTesting/Test/Unitdirectory and operate them.

 

To make Testing faster, let’s comment other lines under testsuite tag as per follows:

 

That’s it!! Now you are ready to start Unit Testing.

 

Unit Testing

To run the test, open terminal and go to your magento directory and run the following commands:

 

  • cd dev/tests/unit
  • php ../../../vendor/phpunit/phpunit/phpunit

 

It will give you the following output:

 

Here, you will that test has been done successfully as a string with only alphabets has been passed in testGetText() function in /app/code/Bizspice/UnitTesting/Test/Unit/Model/AlphabetTest.php -

 

public function testGetText() {        $this->_actualResult = $this->_alphabet->getText("This is my testing string");        $this->_desiredResult = "This is my testing string";        $this->assertEquals($this->_desiredResult, $this->_actualResult);  }

 

Now, to get the failure result, let’s change the string passed in above function and replace the function with the following code:

 

public function testGetText() {     $this->_actualResult = $this->_alphabet->getText("This is my testing string2222");  $this->_desiredResult = "This is my testing string";     $this->assertEquals($this->_desiredResult, $this->_actualResult); }

 

Run the following command in terminal again:

 

php ../../../vendor/phpunit/phpunit/phpunit

 

And you will see the following result:

 

Assertions For Testing

So, you have seen the basic implementation of Unit Testing. There is a function assertEquals has been used in testGetText() function in /app/code/Bizspice/UnitTesting/Test/Unit/Model/AlphabetTest.php. This is an assertion to compare the result for testing.

 

Following are the few types of Assertions:

 

assertTrue($x) Fail if $x is false assertFalse($x) Fail if $x is true assertNull($x)  Fail if $x is set assertNotNull($x)   Fail if $x not set assertIsA($x, $t)   Fail if $x is not the class or type $t assertNotA($x, $t)  Fail if $x is of the class or type $t assertEqual($x, $y) Fail if $x == $y is false assertNotEqual($x, $y)  Fail if $x == $y is true assertWithinMargin($x, $y, $m)  Fail if abs($x - $y) < $m is false assertOutsideMargin($x, $y, $m) Fail if abs($x - $y) < $m is true assertIdentical($x, $y) Fail if $x == $y is false or a type mismatch assertNotIdentical($x, $y)  Fail if $x == $y is true and types match assertReference($x, $y) Fail unless $x and $y are the same variable assertClone($x, $y) Fail unless $x and $y are identical copies assertPattern($p, $x)   Fail unless the regex $p matches $x assertNoPattern($p, $x) Fail if the regex $p matches $x expectError($x) Fail if matching error does not occour expectException($x) Fail if matching exception is not thrown ignoreException($x) Swallows any upcoming matching exception assert($e)  Fail on failed expectation object 

 

If you have been curious to know more about Unit Testing, check this link (https://phpunit.de/)