Automated Testing with Magento




Meet-Magento DE 2013
@VinaiKopp
"It's impossible to test Magento"
Anonymous Magento Developer

Whats available?



Magento Test Automation Framework

MTAF



Magento Test Automation Framework

PHPUnit & Selenium2 QA Testing

MTAF



Magento Inc.
Released 22. Feb 2012

MTAF



MTAF on github

MTAF

Setup


Up to date installation instructions
on the Magento bugathon wiki

MTAF

Setup


The Magento Instance and
the MTAF can be installed separately

MTAF

Directory Structure

```bash taf/ ├── fixture/ ├── framework/ └── testsuite/ ```

MTAF

Define Fixtures in yml

```yml product_special_price: product_attribute_set: Default general_name: Special Price Simple Product(%randomize%) general_sku: special_price_sku_%randomize% general_url_key: special-price-product-%randomize% general_status: Enabled ... inventory_qty: 999 inventory_stock_availability: In Stock websites: Main Website categories: Default Category ```

MTAF

Load yml Fixtures

```php // Load the section "product_special_price" from the file "Product.yml" $productData = $this->loadDataSet('Product', 'product_special_price'); ```

MTAF

Helpers

```php $this->productHelper()->createProduct($productData); ```

MTAF

UI Maps

```yml product_detail: mca: %productUrlKey%.html title: %productName% uimap: fieldsets: - price_box: pageelements: special_price: //div[@class="price-box"]/p[@class="special-price"]/span[@class="price"] ```

MTAF

Using UI Maps

```php $this->frontend('product_detail'); $this->assertTrue( $this->controlIsPresent('pageelement', 'special_price'), 'Special price not found on product detail page.' ); ```

MTAF

Example

Is product special price is displayed on frontend?
(on github)

Backport of Magento 2 Tests

PHPUnit-Magento Integration


Backported by Techdivision
Released 25. March 2013

Backport of Magento 2 Tests



TechDivision_MagentoUnitTesting
backport on github

Backport of Magento 2 Tests


~1200 Integration, ~33 Unit
(sans skipped/incomplete)

Backport of Magento 2 Tests


PHPUnit based - no Selenium

Backport of Magento 2 Tests

Directory Structure

```bash htdocs/ ├── app/ ├── dev/ │ └── tests/ │    ├── integration/ │    │ ├── framework/ │    │ └── testsuite/ │    ├── performance/ │    ├── static/ │    └── unit/ └── skin/ ```

Backport of Magento 2 Tests

Data Fixtures

```php /** * @magentoDataFixture Vinai/Catalog/_files/filterCollectionProducts.php */ ```
Kinda like setup scripts

Backport of Magento 2 Tests

Config Fixtures

```php /** * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 0 */ ```

Backport of Magento 2 Tests

Test Isolation

```php /** * Reset config and db cache and re-initialize app for each test * @magentoAppIsolation enabled */ ```

Backport of Magento 2 Tests

Testing Controllers

```php class Magento_Test_TestCase_ControllerAbstract ... { public function dispatch() {} public function assertHeaderPcre() {} public function getRequest() {} public function getResponse() {} } ```

Backport of Magento 2 Tests

Rewriting of Tests

```php /** * @magentoRewriteTestMethod Mage_Catalog_Helper_DataTest::testGetProductUrl() */ ```

Backport of Magento 2 Tests

Mocks

PHPUnit_Framework_MockObject_MockObject

Backport of Magento 2 Tests

Example

Test collection filtering by custom attribute
(on github)

EcomDev_PHPUnit

PHPUnit-Magento Integration

By @IvanChepurnyi of EcomDev

EcomDev_PHPUnit


on github
on Magento Connect

EcomDev_PHPUnit


Tests live under the module directories
(for example app/code/local/Acme/Foo/Test)

EcomDev_PHPUnit


```bash [Acme_Foo] ├── Test/ │   └── Model/ │   ├── FooTest.php │   ├── expectations/ │   │   └── testFooDoesX.yaml │   ├── fixtures/ │   │   └── testFooDoesX.yaml │   └── providers/ │   └── testFooDoesX.yaml └── etc/ └── config.xml ```

EcomDev_PHPUnit



Yaml Fixtures

EcomDev_PHPUnit

Fixtures

Scope Fixtures
```yml scope: website: - website_id: 1 code: base name: Main Website default_group_id: 1 ```

(Websites, Store Groups & Store Views)

EcomDev_PHPUnit

Fixtures

Config Fixtures
```yml config: default/catalog/frontend/flat_catalog_product: 0 stores/german/catalog/frontend/list_allow_all: 1 ```

EcomDev_PHPUnit

Fixtures

Table Fixtures
```yml tables: customer/customer_group: - customer_group_id: 5 customer_group_code: Test Group tax_class_id: 3 ```

EcomDev_PHPUnit

Fixtures

EAV Fixtures
```yml eav: catalog_product: - entity_id: 1 type_id: simple sku: product1 name: Product One url_key: product_one stock: qty: 1000.00 is_in_stock: 1 website_ids: - base price: 12.99 status: 1 ```

EcomDev_PHPUnit

Fixtures

Class scope fixtures
```php /** * @loadSharedFixture */ class Acme_Foo_Test_Model_MyTest ... ```

EcomDev_PHPUnit

Fixtures

Test scope fixtures
```php /** * @loadFixture */ public function testMyFoo() ```

Stacks onto shared fixtures!

EcomDev_PHPUnit

More Annotations

Registry clean-up
```php /** * @singleton core/session * @helper catalog/product_flat */ public function testDoesFooMakeBar() ```

EcomDev_PHPUnit

Mocks

```php $mockAddress = $this->getModelMock('customer/address'); $this->replaceByMock('model', 'customer/address', $mockAddress); ```

EcomDev_PHPUnit

Testing Controllers

```php class EcomDev_PHPUnit_Test_Case_Controller ... { public function dispatch() {} public function assertRequest() {} public function assertRequestDispatched() {} public function assertRequestForwarded() {} public function assertRequestRoute() {} public function assertRequestRouteName() {} public function assertRequestControllerName() {} public function assertRequestControllerModule() {} public function assertRequestActionName() {} public function assertRequestBeforeForwardedRoute() {} public function assertResponseHeaderSent() {} public function assertResponseBodyContains() {} public function assertResponseBodyRegExp() {} public function assertResponseBodyJson() {} public function assertResponseHttpCode() {} public function assertRedirect() {} public function assertRedirectTo() {} public function assertRedirectToUrl() {} public function assertRedirectToUrlStartsWith() {} public function assertRedirectToUrlContains() {} public function assertLayoutLoaded() {} public function assertLayoutRendered() {} public function assertLayoutHandleLoaded() {} public function assertLayoutBlockCreated() {} public function assertLayoutBlockRendered() {} public function assertLayoutBlockTypeOf() {} public function assertLayoutBlockParentEquals() {} public function assertLayoutBlockAfter() {} public function assertLayoutBlockActionInvoked() {} public function assertLayoutBlockProperty() {} public function mockAdminUserSession() {} // There are many more... } ```

EcomDev_PHPUnit Test

Example

Test customer authentication
(on github)

MageTest

Light Weight PHPUnit-Magento Integration

by @AlistairStead of Inviqa / Session Digital

MageTest


on github

MageTest

Directory Structure

```bash htdocs/ ├── app/ ├── tests │   ├── bootstrap.php │   ├── integration │   ├── phpunit.xml.dist │   └── unit ├── skin/ ├── ... └── var/ ```

MageTest

Fixture Factories

```php $this->_product = MageTest_Fixture_Product::create(); ```
Factories for customers, products, orders & invoices

MageTest

Mock Singletons & Models

```php $mockCustomer = $this->getModck('Mage_Customer_Model_Customer'); Mage::getConfig()->setModelInstanceMock('catalog/product', $mockCustomer); ```

MageTest

Testing Controllers

```php class MageTest_PHPUnit_Framework_ControllerTestCase ... { public function assertControllerModule() {} public function dispatch() {} public function assertRoute() {} public function assertNotRoute() {} } ```

MageTest

Example

Test catalog/product_url returns the correct SEO URL
(on github)

BehatMage

Behat-Magento Integration

By @AlistairStead, Marcello Duarte & more
(Started at MageHack London 2012)

BehatMage


Test BUSINESS SPECIFICATIONS
(NOT TECH SPECS)

BehatMage


on github

BehatMage

Directory Structure

```bash project/ ├── features/ │   ├── admin_configures_guest_checkout.feature │   └── bootstrap/ │   ├── FeatureContext.php │   └── GuestCheckoutContext.php ├── htdocs/ │   ├── app/ │   ├── ... │   └── var/ └── vendor/ ```

BehatMage

Features

```Cucumber Feature: The Admin User can disable or enable guest checkout So the amount of charge backs can be minimized, as an Admin User, I want to be able to enable or disable the guest checkout. ```

BehatMage

Scenarios

```Cucumber Scenario: Admin User disables guest checkout Given the Admin User has disabled guest checkout And the following products exist: | sku | name | is_in_stock | qty | | test1 | Test Product 1 | 1 | 99999 | When I am not logged in as a customer And I add "test1" to the cart And I go the the checkout Then I am not able to check out as guest ```

BehatMage

Fixture Factories

Products
Admin Users
Admin session

BehatMage

Translate Business Specifications into PHP Code

Check specifications via Mink WebDriver
or direct Class access.

BehatMage

Example

Check that the guest checkout can be disabled
(on github)

More...


MageSpec, Testify
Do you know more?

What should I build my tests with?

Thank you!


``` if ($q = $you->getQuestion()) { $a = $this->query($q); var_dump($a); } ```
@VinaiKopp