Magento 2.1.18 is the final 2.1.x release. After June 2019, Magento 2.1.x will no longer receive security patches, quality fixes, or documentation updates.
To maintain your site's performance, security, and PCI compliance, upgrade to the latest version of Magento.

Data fixture annotation

A data fixture is a PHP script that sets data you want to reuse in your test. The script can be defined in a separate file or as a local test case method.

Use data fixtures to prepare a database for tests. The Integration Testing Framework (ITF) reverts the database to its initial state automatically. To set up a date fixture, use the @magentoDataFixture annotation.

Format

@magentoDataFixture takes an argument that points to the data fixture as a filename or local method.

1
2
3
/**
 * @magentoDataFixture <script_filename>|<method_name>
 */
  • <script_filename> is a filename of the PHP script.
  • <method_name> is a name of the method declared in the current class.

Principles

  1. Do not use a direct database connection in fixtures to avoid dependencies on the database structure and vendor.
  2. Use an application API to implement your data fixtures.
  3. A method that implements a data fixture must be declared as public and static.
  4. Fixtures declared at a test level have a higher priority then fixtures declared at a test case level.
  5. Test case fixtures are applied to each test in the test case, unless a test has its own fixtures declared.
  6. Annotation declaration at a test case level does not affect tests that have their own annotation declarations.

Usage

As was mentioned above, there are two ways to declare fixtures:

  • as a PHP script file that is used by other tests and test cases.
  • as a local method that is used by other tests in the test cases.

Fixture as a separate file

Define the fixture in a separate file when you want to reuse it in different test cases. To declare the fixture, use the following conventions for a path

  • Relative to dev/tests/integration/<test suite directory>
  • With forward slashes /
  • No leading slash Example: Magento/Cms/_files/pages.php

The ITF includes the declared PHP script to your test and executes it during test run.

The following example demonstrates a simple implementation of a Cms module page test from the Magento codebase.

Data fixture to test a Cms module page (dev/tests/integration/testsuite/Magento/Cms/_files/pages.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/** @var $page \Magento\Cms\Model\Page */
$page = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Cms\Model\Page');
$page->setTitle('Cms Page 100')
    ->setIdentifier('page100')
    ->setStores([0])
    ->setIsActive(1)
    ->setContent('<h1>Cms Page 100 Title</h1>')
    ->setPageLayout('1column')
    ->save();

$page = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Cms\Model\Page');
$page->setTitle('Cms Page Design Blank')
    ->setIdentifier('page_design_blank')
    ->setStores([0])
    ->setIsActive(1)
    ->setContent('<h1>Cms Page Design Blank Title</h1>')
    ->setPageLayout('1column')
    ->setCustomTheme('Magento/blank')
    ->save();

Test case that uses the above data fixture (dev/tests/integration/testsuite/Magento/Cms/Block/PageTest.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\Cms\Block;

class PageTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @magentoAppIsolation enabled
     * @magentoDataFixture Magento/Cms/_files/pages.php
     */
    public function testGetPage()
    {
        $page = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Cms\Model\Page');
        $page->load('page100', 'identifier');
        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
            'Magento\Framework\View\LayoutInterface'
        );
        $pageBlock = $layout->createBlock('Magento\Cms\Block\Page');
        $pageBlock->setData('page', $page);
        $pageBlock->toHtml();
        $this->assertEquals($page, $pageBlock->getPage());
    }
}

Fixture as a method

The following is an example of the testCreatePageWithSameModuleName() test method that uses data from the cmsPageWithSystemRouteFixture() data fixture.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * Test class for \Magento\Cms\Controller\Page.
 */
namespace Magento\Cms\Controller;

class PageTest extends \Magento\TestFramework\TestCase\AbstractController
{
    public function testViewAction()
    {
        $this->dispatch('/enable-cookies');
        $this->assertContains('What are Cookies?', $this->getResponse()->getBody());
    }

    public function testViewRedirectWithTrailingSlash()
    {
        $this->dispatch('/enable-cookies/');
        $code = $this->getResponse()->getStatusCode();
        $location = $this->getResponse()->getHeader('Location')->getFieldValue();

        $this->assertEquals(301, $code, 'Invalid response code');
        $this->assertStringEndsWith('/enable-cookies', $location, 'Invalid location header');
    }

    /**
     * Test \Magento\Cms\Block\Page::_addBreadcrumbs
     */
    public function testAddBreadcrumbs()
    {
        $this->dispatch('/enable-cookies');
        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
            'Magento\Framework\View\LayoutInterface'
        );
        $breadcrumbsBlock = $layout->getBlock('breadcrumbs');
        $this->assertContains($breadcrumbsBlock->toHtml(), $this->getResponse()->getBody());
    }

    /**
     * @magentoDataFixture cmsPageWithSystemRouteFixture
     */
    public function testCreatePageWithSameModuleName()
    {
        $this->dispatch('/shipping');
        $content = $this->getResponse()->getBody();
        $this->assertContains('Shipping Test Page', $content);
    }

    public static function cmsPageWithSystemRouteFixture()
    {
        /** @var $page \Magento\Cms\Model\Page */
        $page = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Cms\Model\Page');
        $page->setTitle('Test title')
            ->setIdentifier('shipping')
            ->setStores([0])
            ->setIsActive(1)
            ->setContent('<h1>Shipping Test Page</h1>')
            ->setPageLayout('1column')
            ->save();
    }
}

Test case and test method scopes

The @magentoDataFixture can be specified for a particular test or for an entire test case. The basic rules for fixture annotation at different levels are:

  • @magentoDataFixture at a test case level makes the framework to apply the declared fixtures to each test in the test case. When the final test is complete, all class-level fixtures are reverted.
  • @magentoDataFixture for a particular test signals the framework to revert the fixtures declared on a test case level and applies the fixtures declared at a test method level instead. When the test is complete, the ITF reverts the applied fixtures.

The integration testing framework interacts with a database to revert the applied fixtures.

Fixture rollback

A fixture that contain database transactions only are reverted automatically. Otherwise, when a fixture creates files or performs any actions other than database transaction, provide the corresponding rollback logic. Rollbacks are run after reverting all the fixtures related to database transactions.

A fixture rollback must be of the same format as the corresponding fixture: a script or a method:

  • A rollback script must be named according to the corresponding fixture suffixed with _rollback and stored in the same directory.
  • Rollback methods must be of the same class as the corresponding fixture and suffixed with Rollback.

Examples:

Fixture/Rollback Fixture name Rollback name
Script Magento/Catalog/_files/categories.php Magento/Catalog/_files/categories_rollback.php
Method \Magento\Catalog\Model\ProductTest::prepareProduct \Magento\Catalog\Model\ProductTest::prepareProductRollback

Restrictions

Do not rely on and do not modify an application state from within a fixture, because application isolation annotation can reset the application state at any moment.

Updated