|
| 1 | +--- |
| 2 | +group: testing |
| 3 | +title: Data fixture annotation |
| 4 | +--- |
| 5 | + |
| 6 | +A data fixture is a PHP script that sets data you want to reuse in your test. |
| 7 | +The script can be defined in a separate file or as a local test case method. |
| 8 | + |
| 9 | +Use data fixtures to prepare a database for tests. |
| 10 | +The Integration Testing Framework (ITF) reverts the database to its initial state automatically. |
| 11 | +To set up a date fixture, use the `@magentoDataFixture` annotation. |
| 12 | + |
| 13 | +## Format |
| 14 | + |
| 15 | +`@magentoDataFixture` takes an argument that points to the data fixture as a filename or local method. |
| 16 | + |
| 17 | +```php?start_inline=1 |
| 18 | +/** |
| 19 | + * @magentoDataFixture <script_filename>|<method_name> |
| 20 | + */ |
| 21 | +``` |
| 22 | + |
| 23 | +- `<script_filename>` is the filename of the PHP script. |
| 24 | +- `<method_name>` is the name of the method declared in the current class. |
| 25 | + |
| 26 | +## Principles |
| 27 | + |
| 28 | +1. Do not use a direct database connection in fixtures to avoid dependencies on the database structure and vendor. |
| 29 | +1. Use an application API to implement your data fixtures. |
| 30 | +1. A method that implements a data fixture must be declared as `public` and `static`. |
| 31 | +1. Fixtures declared at a test level have a higher priority than fixtures declared at a test case level. |
| 32 | +1. Test case fixtures are applied to each test in the test case, unless a test has its own fixtures declared. |
| 33 | +1. Annotation declaration at a test case level does not affect tests that have their own annotation declarations. |
| 34 | + |
| 35 | +## Usage |
| 36 | + |
| 37 | +As mentioned above, there are two ways to declare fixtures: |
| 38 | + |
| 39 | +- as a PHP script file that is used by other tests and test cases. |
| 40 | +- as a local method that is used by other tests in the test cases. |
| 41 | + |
| 42 | +### Fixture as a separate file |
| 43 | + |
| 44 | +Define the fixture in a separate file when you want to reuse it in different test cases. |
| 45 | +To declare the fixture, use one of the following conventions: |
| 46 | + |
| 47 | +- Fixture declaration as a path relative to the test suite directory |
| 48 | + - Relative to `dev/tests/integration/<test suite directory>` |
| 49 | + - With forward slashes `/` |
| 50 | + - No leading slash |
| 51 | + |
| 52 | + Example: |
| 53 | + |
| 54 | + ```php |
| 55 | + /** |
| 56 | + * @magentoDataFixture Magento/Cms/_files/pages.php |
| 57 | + */ |
| 58 | + ``` |
| 59 | + |
| 60 | +- Fixture declaration as a path relative to a module |
| 61 | + - Relative to the directory of a module available in the project |
| 62 | + - With forward slashes `/` |
| 63 | + - No leading slash in the path part of the declaration |
| 64 | + |
| 65 | + Example: |
| 66 | + |
| 67 | + ```php |
| 68 | + /** |
| 69 | + * @magentoDataFixture VendorName_ModuleName::Test/Integration/_files/fixture_name.php |
| 70 | + */ |
| 71 | + ``` |
| 72 | + |
| 73 | +The ITF includes the declared PHP script to your test and executes it during the test run. |
| 74 | + |
| 75 | +The following example demonstrates a simple implementation of a Cms module page test from the Magento codebase. |
| 76 | + |
| 77 | +Data fixture to test a Cms module page: [`dev/tests/integration/testsuite/Magento/Cms/_files/pages.php`][]. |
| 78 | + |
| 79 | +Test case that uses the above data fixture: [`dev/tests/integration/testsuite/Magento/Cms/Block/PageTest.php`][]. |
| 80 | + |
| 81 | +### Fixture as a method |
| 82 | + |
| 83 | +[`dev/tests/integration/testsuite/Magento/Cms/Controller/PageTest.php`][] demonstrates an example of the `testCreatePageWithSameModuleName()` test method that uses data from the `cmsPageWithSystemRouteFixture()` data fixture. |
| 84 | + |
| 85 | +### Test case and test method scopes |
| 86 | + |
| 87 | +The `@magentoDataFixture` can be specified for a particular test or for an entire test case. |
| 88 | +The basic rules for fixture annotation at different levels are: |
| 89 | + |
| 90 | +- `@magentoDataFixture` at a test case level, makes the framework to apply the declared fixtures to each test in the test case. |
| 91 | + When the final test is complete, all class-level fixtures are reverted. |
| 92 | +- `@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. |
| 93 | + When the test is complete, the ITF reverts the applied fixtures. |
| 94 | + |
| 95 | + {:.bs-callout-info} |
| 96 | +The integration testing framework interacts with a database to revert the applied fixtures. |
| 97 | + |
| 98 | +### Fixture rollback |
| 99 | + |
| 100 | +A fixture that contains database transactions only, are reverted automatically. |
| 101 | +Otherwise, when a fixture creates files or performs any actions other than database transaction, provide the corresponding rollback logic. |
| 102 | +Rollbacks are run after reverting all the fixtures related to database transactions. |
| 103 | + |
| 104 | +A fixture rollback must be of the same format as the corresponding fixture, a script or a method: |
| 105 | + |
| 106 | +- A rollback script must be named according to the corresponding fixture suffixed with `_rollback` and stored in the same directory. |
| 107 | +- Rollback methods must be of the same class as the corresponding fixture and suffixed with `Rollback`. |
| 108 | + |
| 109 | +Examples: |
| 110 | + |
| 111 | +Fixture/Rollback | Fixture name | Rollback name |
| 112 | +-----------------|------------------------------------------------------|------------------------------------------------------------- |
| 113 | +Script | `Magento/Catalog/_files/categories.php` | `Magento/Catalog/_files/categories_rollback.php` |
| 114 | +Method | `\Magento\Catalog\Model\ProductTest::prepareProduct` | `\Magento\Catalog\Model\ProductTest::prepareProductRollback` |
| 115 | + |
| 116 | +### Restrictions |
| 117 | + |
| 118 | +Do not rely on and do not modify an application state from within a fixture, because [application isolation annotation][magentoAppIsolation] can reset the application state at any time. |
| 119 | + |
| 120 | +<!-- Link definitions --> |
| 121 | + |
| 122 | +[magentoAppIsolation]: magento-app-isolation.html |
| 123 | +[`dev/tests/integration/testsuite/Magento/Cms/_files/pages.php`]: {{ site.mage2bloburl }}/{{ page.guide_version }}/dev/tests/integration/testsuite/Magento/Cms/_files/pages.php |
| 124 | +[`dev/tests/integration/testsuite/Magento/Cms/Block/PageTest.php`]: {{ site.mage2bloburl }}/{{ page.guide_version }}/dev/tests/integration/testsuite/Magento/Cms/Block/PageTest.php |
| 125 | +[`dev/tests/integration/testsuite/Magento/Cms/Controller/PageTest.php`]: {{ site.mage2bloburl }}/{{ page.guide_version }}/dev/tests/integration/testsuite/Magento/Cms/Controller/PageTest.php |
0 commit comments