Идёт обновление сайта. Несколько дней возможны сбои в оформлении и переводах. Документация работает — если страница выглядит сломанной, обновите её позже.

Документация
L Laravel L intervention/image
Войти
Главная Laravel 10.x Тестирование базы данных

Тестирование базы данных

10.x 7 мар 2026 г.

#Введение

Laravel предоставляет множество полезных инструментов и утверждений, которые упрощают тестирование приложений с базой данных. Кроме того, фабрики моделей и сидеры Laravel позволяют легко создавать тестовые записи в базе данных с использованием Eloquent моделей и их связей. Все эти мощные возможности будут рассмотрены в следующей документации.

#Сброс базы данных после каждого теста

Прежде чем двигаться дальше, давайте обсудим, как сбрасывать базу данных после каждого теста, чтобы данные из предыдущего теста не влияли на последующие. Встроенный в Laravel трейт Illuminate\Foundation\Testing\RefreshDatabase позаботится об этом за вас. Просто используйте этот трейт в вашем классе теста:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Пример базового функционального теста.
     */
    public function test_basic_example(): void
    {
        $response = $this->get('/');

        // ...
    }
}

Трейт Illuminate\Foundation\Testing\RefreshDatabase не выполняет миграции, если схема базы данных актуальна. Вместо этого тест выполняется внутри транзакции базы данных. Поэтому записи, добавленные тестами, которые не используют этот трейт, могут остаться в базе.

Если вы хотите полностью сбросить базу данных, можно использовать трейты Illuminate\Foundation\Testing\DatabaseMigrations или Illuminate\Foundation\Testing\DatabaseTruncation. Однако оба варианта значительно медленнее, чем RefreshDatabase.

#Фабрики моделей

При тестировании может потребоваться добавить несколько записей в базу перед выполнением теста. Вместо того чтобы вручную задавать значения каждого столбца, Laravel позволяет определить набор атрибутов по умолчанию для каждой из ваших Eloquent моделей с помощью фабрик моделей.

Чтобы узнать больше о создании и использовании фабрик моделей для создания моделей, ознакомьтесь с полной документацией по фабрикам моделей. После определения фабрики модели вы можете использовать её в тестах для создания моделей:

use App\Models\User;

public function test_models_can_be_instantiated(): void
{
    $user = User::factory()->create();

    // ...
}

#Запуск сидеров

Если вы хотите использовать сидеры базы данных для заполнения базы во время функционального теста, можно вызвать метод seed. По умолчанию метод seed запускает DatabaseSeeder, который должен запускать все остальные сидеры. Также можно передать конкретный класс сидера в метод seed:

<?php

namespace Tests\Feature;

use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Тест создания нового заказа.
     */
    public function test_orders_can_be_created(): void
    {
        // Запустить DatabaseSeeder...
        $this->seed();

        // Запустить конкретный сидер...
        $this->seed(OrderStatusSeeder::class);

        // ...

        // Запустить массив конкретных сидеров...
        $this->seed([
            OrderStatusSeeder::class,
            TransactionStatusSeeder::class,
            // ...
        ]);
    }
}

Также можно настроить автоматический запуск сидера перед каждым тестом, использующим трейт RefreshDatabase. Для этого определите свойство $seed в базовом классе теста:

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;

    /**
     * Указывает, должен ли запускаться сидер по умолчанию перед каждым тестом.
     *
     * @var bool
     */
    protected $seed = true;
}

Если свойство $seed установлено в true, тест будет запускать класс Database\Seeders\DatabaseSeeder перед каждым тестом с использованием трейта RefreshDatabase. Однако можно указать конкретный сидер, определив свойство $seeder в классе теста:

use Database\Seeders\OrderStatusSeeder;

/**
 * Запускать конкретный сидер перед каждым тестом.
 *
 * @var string
 */
protected $seeder = OrderStatusSeeder::class;

#Доступные утверждения

Laravel предоставляет несколько утверждений для работы с базой данных в ваших функциональных тестах на PHPUnit. Ниже рассмотрены каждое из этих утверждений.

#assertDatabaseCount

Проверяет, что в таблице базы данных содержится указанное количество записей:

$this->assertDatabaseCount('users', 5);

#assertDatabaseHas

Проверяет, что в таблице базы данных есть записи, соответствующие заданным условиям ключ/значение:

$this->assertDatabaseHas('users', [
    'email' => 'sally@example.com',
]);

#assertDatabaseMissing

Проверяет, что в таблице базы данных отсутствуют записи, соответствующие заданным условиям ключ/значение:

$this->assertDatabaseMissing('users', [
    'email' => 'sally@example.com',
]);

#assertSoftDeleted

Метод assertSoftDeleted используется для проверки, что заданная Eloquent модель была "мягко удалена":

$this->assertSoftDeleted($user);

#assertNotSoftDeleted

Метод assertNotSoftDeleted используется для проверки, что заданная Eloquent модель не была "мягко удалена":

$this->assertNotSoftDeleted($user);

#assertModelExists

Проверяет, что заданная модель существует в базе данных:

use App\Models\User;

$user = User::factory()->create();

$this->assertModelExists($user);

#assertModelMissing

Проверяет, что заданная модель отсутствует в базе данных:

use App\Models\User;

$user = User::factory()->create();

$user->delete();

$this->assertModelMissing($user);

#expectsDatabaseQueryCount

Метод expectsDatabaseQueryCount можно вызвать в начале теста, чтобы указать ожидаемое количество запросов к базе данных во время теста. Если фактическое количество запросов не совпадёт с ожидаемым, тест провалится:

$this->expectsDatabaseQueryCount(5);

// Тест...