Magento 2 integration tests

33
Magento 2 integration tests

Transcript of Magento 2 integration tests

Page 1: Magento 2 integration tests

Magento 2integration tests

Page 2: Magento 2 integration tests

What is Magento?One of the most popular Ecommerce platforms

All the stuff that one web shop needs

Used on 1.3% of all websites (http://w3techs.com/technologies/overview/content_management/all)

Based on PHP, MySQL….

Free and paid versions

Modular approach (Catalog, Category, Checkout, Sales…)

Page 3: Magento 2 integration tests

Magento grew over years

Huge number of extensions

Huge number of features

Huge community

Page 4: Magento 2 integration tests

Magento 2Announced 2010

Refactor / rewrite

Goals:

Modern tech stack

Improved performance and scalability

Streamline customizations

Simplify external integrations

Easier installation and upgrades

High code quality and testing

More info: http://alankent.me/2014/05/17/magento-2-goals/

Page 5: Magento 2 integration tests

Magento 2 introduces

Namespaces

Composer

Jquery instead of Prototype

Dependency injection

Service contracts

Plugins

XML Schema validation

Automated tests

Page 6: Magento 2 integration tests

Automated testing vs manual testing

Executed more quickly

Reusable

Everyone can see results

Costs less

More reliable

More interesting

More info: http://www.base36.com/2013/03/automated-vs-manual-testing-the-pros-and-cons-of-each/

Page 7: Magento 2 integration tests

Automated tests in Magento 2

Unit tests

Integration tests

Functional tests

Other tests (performance, legacy...):

More info: http://alankent.me/2014/06/28/magento-2-test-automation/

Page 8: Magento 2 integration tests

Integration tests

Page 9: Magento 2 integration tests

“Integration tests show that the major parts of a system work

well together”

- The Pragmatic Programmer Book

Page 10: Magento 2 integration tests

The official Magento automated testing standard

Integration tests:

Deployed on close to real environment.

Integration tests verify interaction of components between each other and with system environment (database, file system).

The goals are to tackle cross-dependencies between components/modules and environment-related issues.

Integration test can also be considered as a "small" functional test, so its goal to preserve functionality

More info: https://github.com/magento/magento2/wiki/Magento-Automated-Testing-Standard

Page 11: Magento 2 integration tests

Difference from unit tests

Unit tests test the smallest units of code, integration tests test how those units work together

Integration tests touch more code

Integration tests have less mocking and less isolation

Unit tests are faster

Unit tests are easier to debug

Page 12: Magento 2 integration tests

Difference from functional tests

Functional tests compare against the specification

Functional tests are slower

Functional tests can tell us if something visible to the customer broke

Page 13: Magento 2 integration tests

Integration tests in Magento 2

Based on PHPUnit

Can touch the database and filesystem

Have separate database

Separated into modules

Magento core code is tested with integration tests

Make updates easier

From my experience most of the common mistakes would be picked up by integration tests

Page 14: Magento 2 integration tests

Setup

bin/magento dev:test:run integration

cd dev/tests/integration && phpunit -c phpunit.xml

Separate database: dev/tests/integration/etc/install-config-mysql.php.dist

Configuration in dev/tests/integration/phpunit.xml.dist

TESTS_CLEANUP

TESTS_MAGENTO_MODE

TESTS_ERROR_LOG_LISTENER_LEVEL

Page 15: Magento 2 integration tests

Annotations

/** * Test something * * @magentoConfigFixture currency/options/allow USD * @magentoAppIsolation enabled * @magentoDbIsolation enabled */ public function testSomething() {

}

Page 16: Magento 2 integration tests

Annotations

/** * Test something * * @magentoConfigFixture currency/options/allow USD * @magentoAppIsolation enabled * @magentoDbIsolation enabled */ public function testSomething() {

}

Page 17: Magento 2 integration tests

What are annotations

Meta data used to inject some behaviourPlaced in docblocksChange test behaviourPHPUnit_Framework_TestListeneronTestStart, onTestSuccess, onTestFailure, etc

More info: http://dusanlukic.com/annotations-in-magento-2-integration-tests

Page 18: Magento 2 integration tests

@magentoDbIsolation

when enabled wraps the test in a transaction

enabled - makes sure that the tests don’t affect each other

disabled - useful for debugging as data remains in database

can be applied on class level and on method level

Page 19: Magento 2 integration tests

@magentoConfigFixture

Sets the config value

/** * @magentoConfigFixture current_store sales_email/order/attachagreement 1 */

Page 20: Magento 2 integration tests

@magentoDataFixture/dev/tests/integration/testsuite/Magento/Catalog/_files/product_special_price.php

$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()

->create('Magento\Catalog\Model\Product');

$product->setTypeId('simple')

->setAttributeSetId(4)

->setWebsiteIds([1])

->setName('Simple Product')

->setSku('simple')

->setPrice(10)

->setMetaTitle('meta title')

->setMetaKeyword('meta keyword')

->setMetaDescription('meta description')

->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)

->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)

->setStockData(['use_config_manage_stock' => 0])

->setSpecialPrice('5.99')

->save();

Page 21: Magento 2 integration tests

Rollback script

/dev/tests/integration/testsuite/Magento/Catalog/_files/product_special_price_rollback.php

$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create('Magento\Catalog\Model\Product');$product->load(1);if ($product->getId()) { $product->delete();}

Page 22: Magento 2 integration tests

Some examples

Integration tests can do much more

Don’t test Magento framework, test your own code

Page 23: Magento 2 integration tests

Test that that non existing category goes to 404

class CategoryTest extends

\Magento\TestFramework\TestCase\AbstractController

{

/*...*/

public function testViewActionInactiveCategory()

{

$this->dispatch('catalog/category/view/id/8');

$this->assert404NotFound();

}

/*...*/

}

Page 24: Magento 2 integration tests

Save and load entity

$obj = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->get('\LDusan\Sample\Model\ExampleFactory') ->create();$obj->setVar('value');$obj->save();$id = $something->getId();$repo = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->get('\LDusan\Sample\Api\ExampleRepositoryInterface');$example = $repo->getById($id);$this->assertSame($example->getVar(), 'value');

Page 25: Magento 2 integration tests

Real life example, Fooman_EmailAttachments

Most of the stores have terms and agreement

An email is sent to the customer after each successful order

Goal: Provide the option of attaching terms and agreement to order success email

Page 26: Magento 2 integration tests

Send an email and check contents /** * @magentoDataFixture Magento/Sales/_files/order.php * @magentoDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php * @magentoConfigFixture current_store sales_email/order/attachagreement 1 */ public function testWithHtmlTermsAttachment() { $orderSender = $this->objectManager->create('Magento\Sales\Model\Order\Email\Sender\OrderSender'); $orderSender->send($order);

$termsAttachment = $this->getAttachmentOfType($this->getLastEmail(), 'text/html; charset=UTF-8'); $this->assertContains('Checkout agreement content', base64_decode($termsAttachment['Body'])); }

public function getLastEmail() { $this->mailhogClient->setUri(self::BASE_URL . 'v2/messages?limit=1'); $lastEmail = json_decode($this->mailhogClient->request()->getBody(), true); $lastEmailId = $lastEmail['items'][0]['ID']; $this->mailhogClient->resetParameters(true); $this->mailhogClient->setUri(self::BASE_URL . 'v1/messages/' . $lastEmailId); return json_decode($this->mailhogClient->request()->getBody(), true); }

Page 27: Magento 2 integration tests

The View

Layout

Block

Template

Goal: Insert a block into catalog product view page

Page 28: Magento 2 integration tests

Block

/app/code/LDusan/Sample/Block/Sample.php<?php

namespace LDusan\Sample\Block;

class Sample extends \Magento\Framework\View\Element\Template{

}

Page 29: Magento 2 integration tests

Layout

/app/code/LDusan/Sample/view/frontend/layout/catalog_product_view.xml<?xml version="1.0"?><page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <block class="LDusan\Sample\Block\Sample" name="ldusan-sample-block" template="LDusan_Sample::sample.phtml" /> </referenceContainer> </body></page>

Page 30: Magento 2 integration tests

Template

/app/code/LDusan/Sample/view/frontend/templates/sample.phtml

<p>This should appear in catalog product view page!</p>

Page 31: Magento 2 integration tests

Test if block is added correctly<?php

namespace LDusan\Sample\Controller;

class ActionTest extends \Magento\TestFramework\TestCase\AbstractController{ /** * @magentoDataFixture Magento/Catalog/_files/product_special_price.php */ public function testBlockAdded() { $this->dispatch('catalog/product/view/id/' . $product->getId()); $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( 'Magento\Framework\View\LayoutInterface' ); $this->assertArrayHasKey('ldusan-sample-block', $layout->getAllBlocks()); }}

Page 32: Magento 2 integration tests

To summarize

Integration tests are not:

The only tests that you should write

Integration tests are:

A way to check if something really works as expected

Proof that our code works well with the environment

Page 33: Magento 2 integration tests

Thanks!

Slides on Twitter: @LDusan

Questions?