Я только начал использовать 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]']);
}
}


Нет разумного рабочего процесса для запуска тестов в live / dev db с данными и возврата изменений обратно, выполняемых тестами.
Поэтому ваш подход здесь не работает, вместо этого вам следует:
В следующий раз, когда вы запустите свои тесты, все начнется снова с нулевой точки - чистая база данных, это будет сделано в тестах:
use CreatesApplication;use DatabaseMigrations;parent::setUp(); и т. д.
Подробнее об этих методах ...
Боковые примечания:
При таком подходе будет легко протестировать ваше приложение и в средах CI.
Никогда не пишите тесты, которые зависят от данных в вашей dev / live db. Для испытаний все необходимые данные должны быть предоставлены семенами или даже фабриками!
Я думаю, это отличный вопрос. Я нашел инструмент Artisan, который может быть тем, что вы ищете. Вы можете использовать его, чтобы сделать снимок базы данных перед запуском теста, а затем использовать его снова, чтобы загрузить этот снимок, чтобы восстановить базу данных в предыдущее состояние. Я запустил его (используя MYSQL), и он отлично сработал. Надеюсь, это то, что вы ищете. Вот ссылка ...
https://github.com/spatie/laravel-db-snapshots
Вы ищете черту 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 ".
Вы также включили заявление о наиболее частом использовании use Illuminate\Foundation\Testing\DatabaseTransactions;? Это должно быть выше объявления класса. Затем оператор use DatabaseTransactions; должен находиться внутри первой строки класса, как показано выше.
Я добавил строку и теперь больше не получаю ошибок. Однако, когда я создал тест для регистрации пользователя в своей базе данных и добавил строки для использования DatabaseTransactions, база данных по-прежнему сохраняет пользователя в конце теста.
Вы можете опубликовать свой тестовый класс? Возникает ли исключение, какой-то другой ранний выход или он работает до завершения?
Я добавил тест, который пытался использовать с транзакцией базы данных!
Похоже, эта черта работает только при подключении к базе данных по умолчанию. Если вы используете соединение с базой данных по умолчанию, пожалуйста, дважды проверьте, что вы вручную удалили тестовые данные из базы данных, а затем повторите тест. В противном случае, если вы должны использовать соединение с базой данных не по умолчанию, похоже, что Laravel не предоставляет вам решения для этого.
Прежде всего, когда вы запускаете тесты, вы должны использовать совершенно другую базу данных, чем ваша действующая (или разработанная) база данных. Для этого вы должны создать .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'];
}
Да, это отличный пакет, но я не думаю, что это основная цель такого использования. Как насчет отмены тестов в середине работы? Охватывает ли он все запрошенные сценарии? Конечно нет. И все же есть некоторые ремесленные команды, которые вы не хотите использовать. Так не проще ли модифицировать
.env, чтобы он соответствовал правильной тестовой базе данных, и чем переключиться обратно?