architecture
architecture copied to clipboard
Integration test data fixture change proposal
Problem
Actually there is no formal way to customize existing data fixture directly from the test case which leads to duplicated data fixtures.
Solution
Extend the format of data fixture annotation to support a second parameter which will be injected to the data fixture file to customize the fixture for a specific test scenario.
Requested Reviewers
@buskamuza
Interesting idea, but it has several problems:
- Works well with a simple fixture (simple product, cms page), doesn't work well with complex fixtures(quote, order, bundle product) For example if we create some basic factory for quote some other basic types should be passed into it(product as quote item, customer if this is not a guest quote and other...). But if we need some specific quote (with bundle product with specific options) but we have a factory for simple bundle product, json for such quote became huge because wee need to create such product inside annotation via json.
- It is difficult to transfer data from other fixtures. You have to do everything inside (duplication of creation) or transfer static data from the outside, which is not always possible, since most entity relations work through the IDs. For example product with category. You have already created category in another fixture and you need to path category id into your fixture.
- In case of a big fixture, json becomes unreadable, the name of the fixture isn't informative, and we just transfer static data from the fixture to test annotation. For example If you analyze mentioned above the simple quote constructor should be name something like 'simple_quote'. But if we need some specific quote the name of basic quote will be the same. We just need to add huge json to annotation. After this we need analyze all json to understand difference between this and simple quote. Currently, to understand a quote type simply enough read a name.
- This fixtures is untyped, out of the box it is not clear how to use it.
- Most of all simple fixtures already created.
@mykhailomatiola This proposal is not focused on how you create fixtures data or how you create complex entities like quote, bundle product ... The main idea is to make fixtures data customizable from the test. The factory class in the example is not the main purpose of this proposal but simply a code isolation to make the data fixture file more readable. I agree with you on the issue-3. But most of the time you will not need to customize all data. That's a rare situation and probably would be better in that case to create a new fixture file. I believe the data fixture should have already default data like in the example.
In case of a big fixture, json becomes unreadable
There is an ability to use a class method as fixture. Could you add information about how it will work in such cases?
Example of usage: https://github.com/magento/magento2/blob/2.4-develop/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php#L147 https://github.com/magento/magento2/blob/2.4-develop/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php#L110
@dhorytskyi I believe in this case the JSON will be passed as the function parameter like the following
/**
* @magentoDataFixture roleDataFixture {"role":{"name":"admin_role"}, "someVar": "value"}
*/
public function testGetRole()
{
}
public static function roleDataFixture(array $data)
{
}
Or we could unpack the data array across function parameters.
public static function roleDataFixture(array $role, string $someVar)
{
}
But you will rarely need to customize function data fixture as they're written for your test only.
@buskamuza @dhorytskyi I have updated the proposal with the following changes:
- Replace JSON format with a data provider method that returns an array of data which will be used to customize fixtures and resolve dependencies between fixtures
- Add ability to define and resolve dependencies between fixtures
- Extend overrides.xml (Integration tests extensibility) to support fixture data customization
- Add an alternative solution to replace file based fixtures