Я ищу решение для очистки кеша в Laravel перед запуском всех тестов (обратите внимание, я имею в виду ВСЕ тесты, а не каждый тест):
$this->artisan('cache:clear');
$this->artisan('route:clear');
$this->artisan('config:clear');
P.S. Laravel 9 и PHPUnit 9.5
@matiaslauriti Привет, спасибо за совет! Я пришел к существующему проекту, где они запускают эти строки перед каждым тестом из метода setUp
. В документации говорится, что это необходимо только один раз перед тестовым запуском, поэтому в конечном итоге мне пришлось изменить конвейер gitlab, чтобы вместо этого запускать его из консоли. Я подумал, что может быть способ сделать это, используя обычный материал phpunit.
Но вы не говорите, почему у вас возникла эта проблема, что находится в вашем рабочем кеше конвейера? ты куда-то бежишь php artisan optimize
? вы буквально бегаете php artisan config:cache
или route:cache
и т. д.? При выполнении тестов вас не должно волновать это, это ничего не должно менять, просто спрашиваю из любопытства, потому что у меня никогда не было этой проблемы и я не видел, чтобы у кого-то она была.
Добавлять
protected function setUp(): void
{
parent::setUp();
$this->artisan('cache:clear');
$this->artisan('route:clear');
$this->artisan('config:clear');
}
в тестах/TestCase.php
Я имею в виду перед ВСЕМИ тестами, а не перед каждым тестом, извините, если было недостаточно ясно
Вы можете сделать это, создав свой собственный TestCase (или отредактировав исходный TestCase,php
) и добавив следующие задачи в метод createApplication
:
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
Artisan::call('cache:clear');
Artisan::call('route:clear');
Artisan::call('config:clear');
return $app;
}
}
Каждый тест должен расширять этот TestCase вместо Illuminate\Foundation\Testing\TestCase
Вы также можете не кэшировать маршруты и конфигурацию в своей среде разработки. В вашем phpunit.xml вы также можете установить драйвер кеша, который используется во время тестирования, на другой, чем тот, который используется во время разработки, например:
<phpunit
...>
...
<php>
...
<env name = "CACHE_DRIVER" value = "array"/>
...
</php>
</phpunit>
Это избавит вас от необходимости очищать кеши перед запуском тестов.
В этом ответе вы можете узнать больше о кэшировании конфигурации во время тестирования. Там вы также можете найти ссылку на проблему GitHub, в которой говорится об очистке кешей перед запуском тестов.
Я имею в виду перед ВСЕМИ тестами, а не перед каждым тестом, извините, если было недостаточно ясно
Я понимаю @Majesty, в этом случае вы можете добавить его в метод createApplication
, смотрите обновленный ответ.
Я только что проверил ваш подход, добавив var_dump внутрь createApplication
, и кажется, что этот метод также вызывается в каждом тестовом примере.
Я извиняюсь за то, что читал слишком быстро. В этом случае вы можете просто добавить статическую переменную $cacheCleared
, запускать команды только тогда, когда она равна false
, и установить для нее значение true
после запуска команд.
Статическая переменная не будет работать, каждый тест будет создавать другое приложение, и по этой же причине не работает createApplication
.
Можно со статической переменной: stackoverflow.com/a/56086498/4593376. Другим решением было бы проверить, очищен ли кеш.
@piscator Я думаю, вам следует читать более внимательно, а не просто копировать чей-то ответ, ответ, который вы опубликовали, имеет предварительное условие: если все ваши тесты буквально содержатся в одном классе, и в большинстве случаев ваши тесты не должны быть в одном классе.
Я тестировал статические переменные раньше, и поэтому я сказал, что это не сработает.
Я не копировал ничей ответ, связанный ответ объясняет, что вы можете добавить статическую переменную в базовый класс. Статическая переменная будет общей. Странно, что в вашем случае это не сработало, я использовал его во многих проектах, где он работал. Возможно, что-то не так, но я боюсь, что мы не сможем решить это в ходе этого обсуждения.
Насколько мне известно, такого способа сделать это нет, потому что это не область юнит-тестов.
Модульные тесты предназначены для установки одинаковой среды для каждого теста, среда для всех тестов не входит в его обязанности.
Но вы все равно можете обойти это, создав пользовательскую команду для вызова config:clear
и test
.
1. Создайте пользовательскую команду.
php artisan make:command test
2. Отредактируйте тестовую команду.
Путь по умолчанию будет app/Console/Commands/test.php
.
...
/**
* Execute the console command.
*/
public function handle()
{
$this->call('cache:clear');
$this->call('route:clear');
$this->call('config:clear');
$this->call('test');
}
3. Вызовите модульные тесты с помощью собственной тестовой команды.
Если вы не изменили значение по умолчанию $signature
, app:test
будет командой по умолчанию, которую вы только что создали.
Запустите php artisan app:test
, чтобы вызвать модульные тесты.
Интересный подход, но как вы собираетесь добавлять аргументы командной строки при запуске тестов (например, фильтры, покрытие, параллель)? При таком подходе это невозможно, иначе вам придется каждый раз добавлять аргументы в свою пользовательскую консольную команду, что не очень эффективно.
@piscator У Laravel есть способы добавить аргументы в пользовательскую команду, вы можете прочитать документ Laravel, чтобы узнать, как это сделать. И это не проблема, которую задал этот пост.
На мой взгляд, кажется, вы не заметили, что createApplication()
будет вызываться каждым тестом, у меня была такая же проблема раньше, как и в этом посте.
В моем случае я пытаюсь создать данные для тестирования, перед началом теста я пробовал много способов, даже как вы ответили, используя createApplication()
или setUp()
, просто нет способа достичь того, чего я действительно хочу.
И в итоге я получил два решения: одно — это пользовательская команда, такая как ответ, который я опубликовал, другой способ — использовать .env.testing и создать тестовую базу данных для модульного теста.
Вам придется добавить все аргументы вручную в $this->call('test');
Честно говоря, для вас нет решения, просто никогда не запускайте
xxx:cache
раньше... Я не уверен, почему у вас возникла эта проблема, если она для вашей команды, для вас или кого-то. Это требует, чтобы вы знали, с чем вы работаете, и если это для кого-то младшего, просто скажите им никогда не запускать эти команды локально, а если они это сделали, просто запустите каждую очистку один раз и готово ... Вы все еще можете использовать оболочку, это был бы лучший подход...