e-Zest members share technology ideas to foster digital transformation.

Magento 2- Integration tests with PHP unit

Written by Kailash Lambe | Oct 4, 2018 4:24:00 PM
Magento 2 provides different types of PHPUnit tests.

  • Unit tests
  • Functional tests
  • Integration tests
In this blog, I am focused on Integration tests.

Integration tests

The purpose of integration test is to ensure that the functionality (Modules) is working as expected with other modules as well. The integration tests work with a database.

Prerequisite

  • A dedicated test database
  • The test framework database configuration
  • The PHPUnit configuration
Before starting to create an integration test, let’s get familiar with some terminologies which we are going use in integration tests.

Fixtures

Fixtures are a set of values, which can be an object or an array, and it interacts with a test database and confirms that the module/functionality is working as expected.

Annotations

In PHP, annotations are meta data that are used to inject some behaviour. We can achieve this by putting the data in comments above the methods.

Magento default provides different types of annotations, which can be used to set fixtures and annotations such as:

  • @magentoConfigFixture
  • @magentoDbIsolation
  • @magentoDataFixture
  • @magentoAppIsolation
  • @magentoCache
  • @magentoComponentsDir
  • @magentoAdminConfigFixture
  • @magentoAppArea
  • @magentoDataFixtureBeforeTransaction
Let’s create the integration test to add the product into the cart and check the success assertion.

1) Prepare test database

As per Magento recommendations, Integration should use a different database than the one in the real Magento instance.

Create new database with all permissions. For every integration test Magento requires a fresh test database.

2) The test framework database configuration

Copy the file ./dev/tests/integration/etc/install-config-mysql.php.dist to ./dev/tests/integration/etc/install-config-mysql.php and update the database settings as below.




3) The PHPUnit configuration

Copy the file ./dev/tests/integration/phpunit.xml.dist to ./dev/tests/integration/phpunit.xml and update the testsuites settings as per module requirement. If you don’t comment the rest of the testsuites then the Magento core testsuites will run and it will take a hours for completion.

Code in plain text -
<!-- Test suites definition -->
<testsuites>
<!-- Memory tests run first to prevent influence of other tests on accuracy of memory measurements -->
<!-- testsuite name="Memory Usage Tests">
<file>testsuite/Magento/MemoryUsageTest.php</file>
</testsuite>
<testsuite name="Magento Integration Tests">
<directory suffix="Test.php">testsuite</directory>
<exclude>testsuite/Magento/MemoryUsageTest.php</exclude>
</testsuite -->
<testsuite name="CartTestIntegration">
<directory suffix="Test.php">../../../app/code/Ezest/*/Test/Integration</directory>
<exclude>../../../app/code/Magento</exclude>
<exclude>../../../vendor/magento</exclude>
</testsuite>
</testsuites>

4) Integration PHP file
Create the Magento module and create one main integration file as below at location, ./app/code/Ezest/Integration/Test/Integration/Controller/AddToCartTest.php


Code in plain text-

<?php
namespace Ezest\Integration\Test\Integration\Controller;
class AddToCartTest extends \Magento\TestFramework\TestCase\AbstractController {
/**
* @magentoDbIsolation enabled
* @magentoAppIsolation enabled
*
*/
public function testAddToCartProducts()
{
$productId = 1;
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$cart = $objectManager->create('Magento\Checkout\Model\Cart');
$formKey = $objectManager->create('Magento\Framework\Data\Form\FormKey');
$product = $objectManager->create('Magento\Catalog\Model\Product');
$params = array( 'form_key' => $formKey->getFormKey(),
'product' => $productId,
'qty' =>1 //quantity of product
);
$_product = $product->load($productId);
$cart->addProduct($_product, $params);
$cart->save();
$this->dispatch('checkout/cart/');
$this->assertContains('"items_count":"1"', $this->getResponse()->getBody());
$this->assertNotContains('"items_count":"0"', $this->getResponse()->getBody());
}
}
As you can see, we have used two annotations here,

  • @magentoDbIsolation enabled
When this annotation is enabled, each of the tests will be bundle inside a transaction and rolled back on completion.

  • @magentoAppIsolation enabled

When this annotation is enabled, the application will be restarted on each test run.

5) Run the test command as below,

php bin/magento dev:tests:run integration
You will see an output like and the product will be added to the quote table.


TESTS_CLEANUP constant:

Default value:

<const name="TESTS_CLEANUP" value="disabled"/>

if this constant is set to enabled, the integration test framework will clean the test database and reinstall Magento on every test run. This way, any new modules will be automatically picked up, and any cruft that might have been left over from previous test runs will be removed. It also causes the test framework to flush the test Magento configuration.
If we disable this configuration, the test execution will start much quicker, consequently the developer must manually flush the cache and the database when needed.

To force the test framework to regenerate the cache and the other files, remove the directory
rm -r dev/tests/integration/tmp/sandbox-*