Magento 2 integration tests
-
Upload
dusan-lukic -
Category
Software
-
view
846 -
download
0
Transcript of Magento 2 integration tests
Magento 2integration 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…)
Magento grew over years
Huge number of extensions
Huge number of features
Huge community
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/
Magento 2 introduces
Namespaces
Composer
Jquery instead of Prototype
Dependency injection
Service contracts
Plugins
XML Schema validation
Automated 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/
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/
Integration tests
“Integration tests show that the major parts of a system work
well together”
- The Pragmatic Programmer Book
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
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
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
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
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
Annotations
/** * Test something * * @magentoConfigFixture currency/options/allow USD * @magentoAppIsolation enabled * @magentoDbIsolation enabled */ public function testSomething() {
}
Annotations
/** * Test something * * @magentoConfigFixture currency/options/allow USD * @magentoAppIsolation enabled * @magentoDbIsolation enabled */ public function testSomething() {
}
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
@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
@magentoConfigFixture
Sets the config value
/** * @magentoConfigFixture current_store sales_email/order/attachagreement 1 */
@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();
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();}
Some examples
Integration tests can do much more
Don’t test Magento framework, test your own code
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();
}
/*...*/
}
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');
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
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); }
The View
Layout
Block
Template
Goal: Insert a block into catalog product view page
Block
/app/code/LDusan/Sample/Block/Sample.php<?php
namespace LDusan\Sample\Block;
class Sample extends \Magento\Framework\View\Element\Template{
}
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>
Template
/app/code/LDusan/Sample/view/frontend/templates/sample.phtml
<p>This should appear in catalog product view page!</p>
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()); }}
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