Что вы использовали для создания фикстур (тестовых данных) в предыдущих проектах на PHP?

Ответ

В Symfony-проектах основным инструментом был DoctrineFixturesBundle в комбинации с Faker для генерации правдоподобных данных. Это позволяло быстро наполнять базу для разработки, тестирования и демо-стендов.

Базовый пример фикстуры для сущности Product:

// src/DataFixtures/ProductFixtures.php
namespace AppDataFixtures;

use AppEntityProduct;
use DoctrineBundleFixturesBundleFixture;
use DoctrinePersistenceObjectManager;
use FakerFactory;

class ProductFixtures extends Fixture
{
    public function load(ObjectManager $manager): void
    {
        $faker = Factory::create('ru_RU');

        for ($i = 0; $i < 50; $i++) {
            $product = new Product();
            $product->setName($faker->words(3, true));
            $product->setDescription($faker->paragraph());
            $product->setPrice($faker->randomNumber(5, false));
            $product->setCreatedAt($faker->dateTimeThisYear);

            $manager->persist($product);
            // Сохраняем ссылку для использования в других фикстурах
            $this->addReference('product_' . $i, $product);
        }
        $manager->flush();
    }
}

Для сложных связей использовали:

  • Ссылки (References): Чтобы связать, например, заказ (Order) с существующим пользователем (User) из другой фикстуры.
    // В OrderFixtures
    $user = $this->getReference('user_admin');
    $order->setCustomer($user);
  • Зависимые фикстуры: Группировка и порядок загрузки через dependencies в аннотации ORMFixture.
  • Пургатор (Purger): Для очистки базы с отключением foreign key checks (--purge-with-truncate) перед загрузкой новых данных.

В некоторых проектах также пробовали AliceBundle для описания фикстур в YAML-файлах, что было удобно для команд, где не все разработчики хотели писать PHP-код для генерации данных.

Ответ 18+ 🔞

Блин, смотри, раньше в Symfony-проектах у нас был один проверенный способ набить базу тестовыми данными — это DoctrineFixturesBundle в связке с Faker. Ну, чтобы не придумывать названия товаров вроде «asdf123», а генерировать что-то похожее на правду. Для разработки, тестов или чтобы заказчику демку показать — самое то, ёпта.

Вот простейший пример, как мы обычно делали для какой-нибудь сущности Product:

// src/DataFixtures/ProductFixtures.php
namespace AppDataFixtures;

use AppEntityProduct;
use DoctrineBundleFixturesBundleFixture;
use DoctrinePersistenceObjectManager;
use FakerFactory;

class ProductFixtures extends Fixture
{
    public function load(ObjectManager $manager): void
    {
        $faker = Factory::create('ru_RU');

        for ($i = 0; $i < 50; $i++) {
            $product = new Product();
            $product->setName($faker->words(3, true));
            $product->setDescription($faker->paragraph());
            $product->setPrice($faker->randomNumber(5, false));
            $product->setCreatedAt($faker->dateTimeThisYear);

            $manager->persist($product);
            // Сохраняем ссылку для использования в других фикстурах
            $this->addReference('product_' . $i, $product);
        }
        $manager->flush();
    }
}

А вот когда связи начинали закручиваться — тут уже приходилось голову ломать. Волнение ебать начиналось настоящее.

  • Ссылки (References): Чтобы, например, не тыкать заказы (Order) в пустоту, а привязать к реальному пользователю (User) из другой фикстуры. Делали так:
    // В OrderFixtures
    $user = $this->getReference('user_admin');
    $order->setCustomer($user);

    Главное — не перепутать ключи, а то получишь ReferenceNotFoundException, и всё, приехали.

  • Зависимые фикстуры: Чтобы не гадать, что загрузится раньше — пользователи или их заказы, — использовали dependencies. Порядок — наше всё.
  • Пургатор (Purger): Когда нужно было всё снести и начать с чистого листа, особенно если в базе были связи по внешним ключам. Флаг --purge-with-truncate был нашим спасителем, иначе каскадное удаление могло всё похерить.

Были, конечно, и другие эксперименты. В одном проекте, например, внедрили AliceBundle. Суть в том, что фикстуры можно было описывать в YAML-файлах. Для части команды, которая не хотела вникать в PHP-код ради генерации данных, это было спасением. Но, честно говоря, когда логика усложнялась, YAML-файлы превращались в пиздопроебибну с кучей вложенностей, и проще было вернуться к старому доброму PHP. В общем, инструмент на любителя, но для простых случаев — вполне ничего.