One of the biggest advantages of Magento 2 compared to Magento 1 is the integrated testing framework for automated testing. It makes automated testing much easier.

A simple example

An integration test can be as simple as this:

app/code/IntegerNet/CategoryDisplay/Test/Integration/Controller/NewProductsCategoryTest.php

Belonging to that, there are two fixture files containing predefined Categories and Products:

app/code/IntegerNet/CategoryDisplay/Test/Integration/_files/categories.php:

app/code/IntegerNet/CategoryDisplay/Test/Integration/_files/products.php:

The Integration Test presented above is for testing a new functionality which allows to set the display mode of a category to “New Products”. If set, the category will show new products only instead of those which are assigned to the category.

How Integration Tests work internally

Integration Tests use a separate Magento installation on a seperate database for testing. It is installed automatically, using the codebase of your project including all activated modules. All setup scripts are executed before the first test is performed. This takes about a minute and can be skipped under certain circumstances, see below.

For each single test, all code is executed inside a database transaction which is rolled back after that so the database will be back in the original state. This allows for full encapsulation, I haven’t recognized any side effects so far.

Set Up Integration Tests for Magento 2

There are a few simple steps to do before you can run your first integration test:

  1. Create a new empty database, i.e. “magento_integration_tests” or “<projectname>_integration_tests”.
  2. Copy the file  dev/tests/integration/etc/install-config-mysql.php.dist to  dev/tests/integration/etc/install-config-mysql.php and adjust the access data to your newly created database. Attention: don’t change the backend-frontname setting!
  3. Copy the file  dev/tests/integration/phpunit.xml.dist to  dev/tests/integration/phpunit.xml. If you don’t adjust the file after that, you’ll be running the Magento 2 core testsuite which will take a few hours. Change the part inside <testsuites>...</testsuites>

    With this change, you tell PHPUnit to test only those files which match the pattern  /app/code/IntegerNet/*/Test/Integration/*/*Test.php, for example app/code/IntegerNet/CategoryDisplay/Test/Integration/Controller/NewProductsCategoryTest.php. Please adjust the pattern to your own Namespace(s).
  4. Run the Magento 2 command line tool with the following parameters:

    You’ll see the output as follow:

Use the IDE for executing Tests

I like to use PhpStorm to execute the tests. The usability is better than on the command line, and I don’t have to switch tools. Plus, here I have the possibility to easily use a debugger on the integration tests.

PHPUnit in PhpStorm - Run

If you do it for the first time, there will be two settings which have to be made:

PHPUnit in PhpStorm - Fix Php Interpreter

Just select the correct PHP interpreter (at least PHP 5.6) for the integration tests.

PHPUnit in PhpStorm - Fix Custom Loader

Fix this by setting the custom loader as follows:

PHPUnit in PhpStorm - Custom Loader Selection

As a PHPUnit executable comes with Magento 2, you won’t have to install any additional tools.

Now the testsuite is being run:

Running PHPUnit inside PhpStorm

Running a single Test Class

If you don’t want to run the whole testsuite but a single file instead, it’s possible with PhpStorm too. Click right on the file in the tree and choose “Run”:

Run single file in PhpStorm

The test will fail at first try because the configuration isn’t correct yet. You can now adjust the configuration in the top PhpStorm toolbar:

Run single file in PhpStorm Edit Configuration

Now, set the alternative configuration file to your phpunit.xml:

Auswahl_032

If you click “Run” now, your integration test will be executed.

What I like about Magento 2 Integration Tests

I don’t come from a testing background. I tried to do integration and unit tests in Magento 1 using the EcomDev_PhpUnit framework, I even got a training by Ivan Chepurnyi, who created it, himself. Still, I found writing those tests very hard, and tests took me much more time than the “real” development, so I abandoned it after a few months.

I tried again with Magento 2, and it is much easier and much more reliable now.

I have chosen Integration Tests as my preferred testing method in Magento 2 for the following reasons:

  • They are, in my opinion, the simplest to implement.
  • They test how the written code interacts with Magento and with the other modules. It is less dependant on assumptions of the developer which may be wrong or incomplete.
  • They can be written using pure PHP.
  • I can use Xdebug as a debugger if something goes wrong.

The biggest advantages compared to integration tests in Magento 1 are:

  • Especially creating fixtures (predefined database contents, like customers, products, categories, configuration settings…) is much faster and much more reliable (instead of hard-to-debug YAML files which have been used in EcomDev_PhpUnit). You can copy a lot of those from the core testsuite ( dev/tests/integration/testsuite).
  • The tests are well encapsulated, so one test doesn’t affect the next tests. This was one of the biggest problems in EcomDev_PhpUnit.
  • In many cases, Mocks or Stubs are not needed. You can still use them if you want / need to.

Of course, they have downsides too:

  • Executing them takes some time as the database is involved. This is a screenshot of the testsuite in one of our current projects:
    Tests Result
  • You can only test the PHP part, but no functions which use JavaScript for example.

A few tips

  1. If you want to speed up the initialization time, you can set the variable  TESTS_CLEANUP inside the phpunit.xml to “disabled” instead of “enabled”. This will skip recreating the Magento installation on every test run. Be careful though: If you added a new module or added a new setup version, it may be necessary to enable the TESTS_CLEANUP temporarily in order to force reinstalling Magento on the test database. Do that if you get errors which you can’t explain.
  2. Depending on your task, you can use Controller Tests which include a call to a URL, as in the example above. Instead of the GET request, you can easily do a POST request as follows:

    The example also shows how to test for redirects and success or error messages.
  3. You can test the behavior for logged in customers with this code:

    Make sure you have a customer with the ID 1 defined in your fixtures.
  4. You can find many examples of integration tests in dev/tests/integration/testsuite.
  5. It is okay (and recommended) to use the object manager in integration tests.

Background: Types of Automated Tests

There are mainly three types of automated tests:

Unit Tests

  • Used to test code blocks like single methods.
  • Written in PHP with the well known testing framework PHPUnit.
  • Called without access to the database.

Integration Tests

  • Testing the behavior of user stories, i.e. if a customer can log in.
  • They test whether a module works well together with other modules.
  • Written in PHP, using PHPUnit as a testing framework too.
  • Using a testing database – it’s more or less a clean parallel installation of Magento 2 which gets installed automatically.

Functional Tests

  • They use a dummy browser to test the whole functionality of the shop, for example from home page to checkout.
  • They typically use Selenium as a testing framework.
  • They are run on a working Magento 2 installation. They can even be executed on the live shop with live data in order to test crucial functionalities like checkout and report if any errors occur.
Andreas von Studnitz

Autor: Andreas von Studnitz

Andreas von Studnitz ist Diplom-Informatiker, Magento-Entwickler und Geschäftsführer von integer_net. Seine Schwerpunkte sind Schnittstellenentwicklung, Backendentwicklung, Beratung und Entwicklerschulungen. Seit 2011 ist er Magento Certified Developer, seit 2014 (für Magento 1) bzw. 2017 (für Magento 2) Magento Certified Solution Specialist.

Mehr Informationen