Сброс базы данных Laravel после теста

Я только начал использовать Laravel Dusk для тестирования своего проекта, и мне нужны некоторые рекомендации. После того, как я запустил все доступные тесты, я хочу иметь возможность вернуть свою базу данных в исходное состояние, прежде чем запускать тесты. (Если бы в моей базе данных были какие-либо записи до запуска тестов, я все равно хотел бы видеть их после запуска тестов. Однако любые записи, созданные во время теста, я не хотел бы видеть их после завершения тестов. ) Есть какие-нибудь указания на то, как я этого добьюсь? Спасибо!

Обновлять:

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class UserRegisterTest extends DuskTestCase
{
    use DatabaseTransactions;
    /**
     * A test for user registration.
     * @group register
     * @return void
     */

    public function testRegisterUser()
    {
        //Register with all info filled out correctly
        $this->browse(function ($browser){
            $browser->visit('/register')
                    ->type('firstName', 'JenLogin')
                    ->type('lastName', 'Zhou')
                    ->type('email', '[email protected]')
                    ->type('bio', 'Hello, this user is for testing login purposes!')
                    ->type('location_zip', '11111')
                    ->type('password', '123456')
                    ->type('password_confirmation', '123456')
                    ->click('.btn-primary')
                    ->assertPathIs('/home')
                    ->click('.dropdown-toggle')
                    ->click('.dropdown-menu li:last-child');

        });

        $this->assertDatabaseHas('users', ['firstName' => 'JenLogin', 'lastName' => 'Zhou', 'email' => '[email protected]']);


    }

    /**
     * Register with duplicate user
     * @group register
     * @return void
     */
    public function testRegisterDuplicateUser(){

        $this->browse(function ($browser){
            $browser->visit('/register')
                ->type('firstName', 'JenLoginDup')
                ->type('lastName', 'Zhou')
                ->type('email', '[email protected]')
                ->type('bio', 'Hello, this user is for testing login purposes!')
                ->type('location_zip', '11111')
                ->type('password', '123456')
                ->type('password_confirmation', '123456')
                ->click('.btn-primary')
                ->assertPathIs('/register')
                ->assertSee('The email has already been taken.');
        });

        $this->assertDatabaseMissing('users', ['firstName' => 'JenLoginDup', 'lastName' => 'Zhou', 'email' => '[email protected]']);
    }

    /**
     * Register with incorrect password confirmation
     * @group register
     * @return void
     */
    public function testRegisterUserNoPassConfirm(){

        $this->browse(function ($browser){
            $browser->visit('/register')
                ->type('firstName', 'JenLoginPass')
                ->type('lastName', 'Zhou')
                ->type('email', '[email protected]')
                ->type('bio', 'Hello, this user is for testing login purposes!')
                ->type('location_zip', '11111')
                ->type('password', '123456')
                ->type('password_confirmation', '888888')
                ->click('.btn-primary')
                ->assertPathIs('/register')
                ->assertSee('The password confirmation does not match.');
        });

        $this->assertDatabaseMissing('users', ['firstName' => 'JenLoginPass', 'lastName' => 'Zhou', 'email' => '[email protected]']);
    }
}
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
3
0
10 548
7

Ответы 7

Нет разумного рабочего процесса для запуска тестов в live / dev db с данными и возврата изменений обратно, выполняемых тестами.

Поэтому ваш подход здесь не работает, вместо этого вам следует:

  1. Создайте отдельную тестовую схему / базу данных для тестов
  2. Переключитесь на test db перед запуском тестов - это можно как-то автоматизировать в зависимости от вашей конфигурации в phpunit и .env.dusk, но это зависит от вашей локальной настройки.
  3. Затем в своих тестах вы создадите все с нуля на чистой базе данных (запускайте миграции, семена, фабрики)
  4. Запустите тесты против этого test db
  5. Для разработки вернитесь к своей базовой БД с текущими данными, на которые не повлияют тесты.

В следующий раз, когда вы запустите свои тесты, все начнется снова с нулевой точки - чистая база данных, это будет сделано в тестах: use CreatesApplication;use DatabaseMigrations;parent::setUp(); и т. д.

Подробнее об этих методах ...

Боковые примечания:

  1. При таком подходе будет легко протестировать ваше приложение и в средах CI.

  2. Никогда не пишите тесты, которые зависят от данных в вашей dev / live db. Для испытаний все необходимые данные должны быть предоставлены семенами или даже фабриками!

Я думаю, это отличный вопрос. Я нашел инструмент Artisan, который может быть тем, что вы ищете. Вы можете использовать его, чтобы сделать снимок базы данных перед запуском теста, а затем использовать его снова, чтобы загрузить этот снимок, чтобы восстановить базу данных в предыдущее состояние. Я запустил его (используя MYSQL), и он отлично сработал. Надеюсь, это то, что вы ищете. Вот ссылка ...

https://github.com/spatie/laravel-db-snapshots

Да, это отличный пакет, но я не думаю, что это основная цель такого использования. Как насчет отмены тестов в середине работы? Охватывает ли он все запрошенные сценарии? Конечно нет. И все же есть некоторые ремесленные команды, которые вы не хотите использовать. Так не проще ли модифицировать .env, чтобы он соответствовал правильной тестовой базе данных, и чем переключиться обратно?

Bart 10.08.2018 03:25

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

use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    use DatabaseTransactions;

    // test methods here
}

Это позволит отслеживать все транзакции, совершенные во время вашего теста, и отменять их по завершении.

примечание: эта черта работает только для соединений с базой данных по умолчанию

Я добавил строку «использовать DatabaseTransactions», но получил эту ошибку «Неустранимая ошибка: черта 'Tests \ Browser \ DatabaseTransactions' не найдена в / Users / jenniferzhou / Documents / Cypress / MarketPlace / tests / Brow‌ ser / UserRegisterTest‌ .php на строка 17 ".

Jennifer Zhou 15.08.2018 00:31

Вы также включили заявление о наиболее частом использовании use Illuminate\Foundation\Testing\DatabaseTransactions;? Это должно быть выше объявления класса. Затем оператор use DatabaseTransactions; должен находиться внутри первой строки класса, как показано выше.

wheelmaker 16.08.2018 04:07

Я добавил строку и теперь больше не получаю ошибок. Однако, когда я создал тест для регистрации пользователя в своей базе данных и добавил строки для использования DatabaseTransactions, база данных по-прежнему сохраняет пользователя в конце теста.

Jennifer Zhou 16.08.2018 16:27

Вы можете опубликовать свой тестовый класс? Возникает ли исключение, какой-то другой ранний выход или он работает до завершения?

wheelmaker 17.08.2018 18:15

Я добавил тест, который пытался использовать с транзакцией базы данных!

Jennifer Zhou 19.08.2018 19:34

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

wheelmaker 13.09.2018 21:55

Прежде всего, когда вы запускаете тесты, вы должны использовать совершенно другую базу данных, чем ваша действующая (или разработанная) база данных. Для этого вы должны создать .env.dusk и установить там:

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=testing_database
DB_USERNAME=root
DB_PASSWORD=pass

в базу данных, используемую только для тестов.

Во-вторых, для Laravel Dusk нельзя использовать только DatabaseTransactions. На самом деле вы должны использовать DatabaseMigrations для тестов Dusk, иначе вы получите неожиданные результаты.

Файл phpunit.xml - это ваше решение, вы можете установить переменные .env в этом файле следующим образом

    <env name = "DB_CONNECTION" value = "testing_mysql"/>
    <env name = "DB_DATABASE_TEST" value = "test"/>

теперь вы можете запускать тесты в отдельной базе данных.

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

<phpunit 
     ...
     bootstrap = "tests/autoload.php"
>

Вы можете положить туда любые очистители или сеялки или что-то вроде

echo 'Migration -begin-' . "\n";
echo shell_exec('php artisan migrate:fresh --seed');
echo 'Migration -end-' . "\n";

Вы можете использовать трейт RefreshDatabase в своих тестовых классах. После каждого теста база данных будет такой же, как перед тестом. Фактически он отбросит все таблицы и снова выполнит миграцию. Если вы не потеряете свои данные, вы можете использовать одну отдельную схему для тестирования.

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

class ExampleTest extends TestCase
{
    use RefreshDatabase;

}

Для нескольких баз данных это помогло мне

class MyTest extends TestCase {
    // Reset the DB between tests
    use DatabaseTransactions;

    // Setting this allows both DB connections to be reset between tests
    protected $connectionsToTransact = ['mysql', 'myOtherConnection'];
}

Другие вопросы по теме