Spec-Zone.ru › CodeIgniter 4

Генерация тестовых данных

Часто для запуска тестов вашего приложения вам потребуются образцы данных. Класс Fabricator использует Faker фзанниото для преобразования моделей в генераторы случайных данных. Используйте фабрики в своих seed-файлах или тестовых случаях для подготовки фиктивных данных для ваших модульных тестов.

  • Поддерживаемые модели
  • Загрузка фабрик
  • Определение форматеров
  • Локализация
  • Генерация данных
  • Указание тестовых данных
  • Вспомогательный инструмент для тестов
  • Счетчики таблиц

Поддерживаемые модели

Fabricator поддерживает любые модели, расширяющие базовую модель фреймворка, CodeIgniter\Model. Вы можете использовать свои собственные пользовательские модели, убедившись, что они реализуют CodeIgniter\Test\Interfaces\FabricatorModel.

class MyModel implements CodeIgniter\Test\Interfaces\FabricatorModel

Примечание

Помимо методов, интерфейс определяет некоторые необходимые свойства для целевой модели. Подробности см. в коде интерфейса.

Загрузка фабрик

В самом простом случае фабрика принимает модель для обработки:

use App\Models\UserModel;
use CodeIgniter\Test\Fabricator;

$fabricator = new Fabricator(UserModel::class);

Параметр может быть строкой, указывающей имя модели, или экземпляром самой модели:

$model = new UserModel($testDbConnection);

$fabricator = new Fabricator($model);

Определение форматеров

Faker генерирует данные, запрашивая их у форматера. При отсутствии определенных форматеров, Fabricator попытается угадать наиболее подходящий вариант на основе имени поля и свойств модели, к которой он относится, используя $fabricator->defaultFormatter в качестве последней возможности. Это может подойти, если имена ваших полей соответствуют стандартным форматерам или если вас не сильно заботит содержимое полей, но в большинстве случаев вам нужно указать используемые форматеры как второй параметр конструктора:

$formatters = [
    'first'  => 'firstName',
    'email'  => 'email',
    'phone'  => 'phoneNumber',
    'avatar' => 'imageUrl',
];

$fabricator = new Fabricator(UserModel::class, $formatters);

Вы также можете изменить форматеры после инициализации фабрики, используя метод setFormatters().

Расширенное форматирование

Иногда стандартного возвращаемого значения форматера недостаточно. Поставщики Faker позволяют использовать параметры для большинства форматеров, чтобы еще больше ограничить сферу случайных данных. Фабрика проверит свою представительскую модель на метод fake(), где вы можете определить, как должны выглядеть сгенерированные данные:

class UserModel
{
    public function fake(Generator &$faker)
    {
        return [
            'first'  => $faker->firstName,
            'email'  => $faker->email,
            'phone'  => $faker->phoneNumber,
            'avatar' => Faker\Provider\Image::imageUrl(800, 400),
            'login'  => config('Auth')->allowRemembering ? date('Y-m-d') : null,
        ];
    }

Обратите внимание, что в этом примере первые три значения эквивалентны предыдущим форматерам. Однако для avatar мы запросили размер изображения, отличный от стандартного, а login использует условие, основанное на конфигурации приложения, ни одно из которых невозможно с помощью параметра $formatters. Возможно, вам потребуется хранить тестовые данные отдельно от производственных моделей, поэтому рекомендуется определить дочерний класс в папке поддержки тестов:

namespace Tests\Support\Models;

class UserFabricator extends \App\Models\UserModel
{
    public function fake(&$faker)
    {

Локализация

Faker поддерживает множество различных локалей. Обратитесь к документации, чтобы узнать, какие поставщики поддерживают вашу локаль. Укажите локаль в качестве третьего параметра при инициализации фабрики:

$fabricator = new Fabricator(UserModel::class, null, 'fr_FR');

Если локаль не указана, будет использоваться локаль, определенная в app/Config/App.php как defaultLocale. Вы можете проверить локаль существующей фабрики, используя метод getLocale().

Генерация данных

После правильной инициализации фабрики легко сгенерировать тестовые данные с помощью команды make():

$fabricator = new Fabricator(UserFabricator::class);
$testUser   = $fabricator->make();
print_r($testUser);

Вы можете получить что-то вроде этого:

array(
    'first'  => "Maynard",
    'email'  => "king.alford@example.org",
    'phone'  => "201-886-0269 x3767",
    'avatar' => "http://lorempixel.com/800/400/",
    'login'  => null,
)

Вы также можете получить несколько таких значений, передав количество:

$users = $fabricator->make(10);

Тип возвращаемого значения make() соответствует типу, определенному в представленной модели, но вы можете принудительно указать тип, используя соответствующие методы напрямую:

$userArray  = $fabricator->makeArray();
$userObject = $fabricator->makeObject();
$userEntity = $fabricator->makeObject('App\Entities\User');

Возвращаемое значение make() готово к использованию в тестах или для вставки в базу данных. В качестве альтернативы, Fabricator включает команду create(), чтобы вставить данные и вернуть результат. Из-за обратных вызовов моделей, форматирования базы данных и специальных ключей, таких как первичный ключ и метки времени, возвращаемое значение create() может отличаться от make(). Вы можете получить что-то вроде этого:

array(
    'id'         => 1,
    'first'      => "Rachel",
    'email'      => "bradley72@gmail.com",
    'phone'      => "741-241-2356",
    'avatar'     => "http://lorempixel.com/800/400/",
    'login'      => null,
    'created_at' => "2020-05-08 14:52:10",
    'updated_at' => "2020-05-08 14:52:10",
)

Аналогично make() вы можете передать количество, чтобы вставить и получить массив объектов:

$users = $fabricator->create(100);

Наконец, могут быть случаи, когда вы хотите протестировать с полным объектом базы данных, но фактически не используете базу данных. create() принимает второй параметр для имитации объекта, возвращая объект с дополнительными полями базы данных, не взаимодействуя с базой данных:

$user = $fabricator(null, true);

$this->assertIsNumeric($user->id);
$this->dontSeeInDatabase('user', ['id' => $user->id]);

Указание тестовых данных

Сгенерированные данные отличны, но иногда вы можете указать конкретное поле для теста, не нарушая конфигурации форматеров. Вместо создания новой фабрики для каждого варианта вы можете использовать setOverrides() для указания значения любого поля:

$fabricator->setOverrides(['first' => 'Bobby']);
$bobbyUser = $fabricator->make();

Теперь любые данные, сгенерированные с помощью make() или create() , всегда будут использовать «Bobby» для поля first:

array(
    'first'  => "Bobby",
    'email'  => "latta.kindel@company.org",
    'phone'  => "251-806-2169",
    'avatar' => "http://lorempixel.com/800/400/",
    'login'  => null,
)

array(
    'first'  => "Bobby",
    'email'  => "melissa.strike@fabricon.us",
    'phone'  => "525-214-2656 x23546",
    'avatar' => "http://lorempixel.com/800/400/",
    'login'  => null,
)

setOverrides() может принимать второй параметр, чтобы указать, должно ли это быть постоянным переопределением или только для одного действия:

$fabricator->setOverrides(['first' => 'Bobby'], $persist = false);
$bobbyUser = $fabricator->make();
$bobbyUser = $fabricator->make();

Обратите внимание, что после первого возврата фабрика перестаёт использовать переопределения:

array(
    'first'  => "Bobby",
    'email'  => "belingadon142@example.org",
    'phone'  => "741-857-1933 x1351",
    'avatar' => "http://lorempixel.com/800/400/",
    'login'  => null,
)

array(
    'first'  => "Hans",
    'email'  => "hoppifur@metraxalon.com",
    'phone'  => "487-235-7006",
    'avatar' => "http://lorempixel.com/800/400/",
    'login'  => null,
)

Если второй параметр не указан, значения по умолчанию сохраняются.

Вспомогательный инструмент для тестов

Зачастую вам потребуется один фиктивный объект для тестирования. Вспомогательный инструмент для тестов предоставляет функцию fake($model, $overrides, $persist = true) для этого:

helper('test');
$user = fake('App\Models\UserModel', ['name' => 'Gerry']);

Это эквивалентно:

$fabricator = new Fabricator('App\Models\UserModel');
$fabricator->setOverrides(['name' => 'Gerry']);
$user = $fabricator->create();

Если вам нужен только фиктивный объект без сохранения его в базе данных, вы можете передать false в параметр persist.

Счетчики таблиц

Часто ваши сгенерированные данные зависят от других сгенерированных данных. Fabricator предоставляет статический счетчик количества сгенерированных элементов для каждой таблицы. Рассмотрим следующий пример:

В вашем проекте есть пользователи и группы. В вашем тестовом случае вы хотите создать различные сценарии с группами разного размера, поэтому вы используете Fabricator для создания набора групп. Теперь вы хотите создать фиктивных пользователей, но не хотите назначать им несуществующий идентификатор группы. Метод fake вашей модели может выглядеть так:

class UserModel
{
    protected $table = 'users';

    public function fake(Generator &$faker)
    {
        return [
            'first'    => $faker->firstName,
            'email'    => $faker->email,
            'group_id' => rand(1, Fabricator::getCount('groups')),
        ];
    }

Теперь создание нового пользователя гарантирует, что он принадлежит действительной группе: $user = fake(UserModel::class);

Fabricator обрабатывает счетчики внутри, но вы также можете получить доступ к этим статическим методам для их использования:

getCount(string $table): int

Возвращает текущее значение для определенной таблицы (по умолчанию: 0).

setCount(string $table, int $count): int

Устанавливает значение для определенной таблицы вручную, например, если вы создали некоторые тестовые элементы без использования фабрики, которые вы все же хотели включить в окончательные счетчики.

upCount(string $table): int

Увеличивает значение для определенной таблицы на единицу и возвращает новое значение. (Это то, что используется внутри с Fabricator::create()).

downCount(string $table): int

Уменьшает значение для определенной таблицы на единицу и возвращает новое значение, например, если вы удалили фиктивный элемент, но хотели отследить изменение.

resetCounts()

Сбрасывает все счетчики. Хорошо вызвать это между тестовыми случаями (хотя использование CIUnitTestCase::$refresh = true делает это автоматически).

© 2014–2020 British Columbia Institute of Technology
Licensed under the MIT License.
https://codeigniter.com/user_guide/testing/fabricator.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API