Как выполнить команду один раз перед всеми тестами?

Я ищу решение для очистки кеша в Laravel перед запуском всех тестов (обратите внимание, я имею в виду ВСЕ тесты, а не каждый тест):

    $this->artisan('cache:clear');
    $this->artisan('route:clear');
    $this->artisan('config:clear');

P.S. Laravel 9 и PHPUnit 9.5

Честно говоря, для вас нет решения, просто никогда не запускайте xxx:cache раньше... Я не уверен, почему у вас возникла эта проблема, если она для вашей команды, для вас или кого-то. Это требует, чтобы вы знали, с чем вы работаете, и если это для кого-то младшего, просто скажите им никогда не запускать эти команды локально, а если они это сделали, просто запустите каждую очистку один раз и готово ... Вы все еще можете использовать оболочку, это был бы лучший подход...

matiaslauriti 13.04.2023 17:26

@matiaslauriti Привет, спасибо за совет! Я пришел к существующему проекту, где они запускают эти строки перед каждым тестом из метода setUp. В документации говорится, что это необходимо только один раз перед тестовым запуском, поэтому в конечном итоге мне пришлось изменить конвейер gitlab, чтобы вместо этого запускать его из консоли. Я подумал, что может быть способ сделать это, используя обычный материал phpunit.

Majesty 14.04.2023 11:26

Но вы не говорите, почему у вас возникла эта проблема, что находится в вашем рабочем кеше конвейера? ты куда-то бежишь php artisan optimize? вы буквально бегаете php artisan config:cache или route:cache и т. д.? При выполнении тестов вас не должно волновать это, это ничего не должно менять, просто спрашиваю из любопытства, потому что у меня никогда не было этой проблемы и я не видел, чтобы у кого-то она была.

matiaslauriti 14.04.2023 22:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
3
81
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Добавлять

protected function setUp(): void
{
    parent::setUp();
    $this->artisan('cache:clear');
    $this->artisan('route:clear');
    $this->artisan('config:clear');
}

в тестах/TestCase.php

Я имею в виду перед ВСЕМИ тестами, а не перед каждым тестом, извините, если было недостаточно ясно

Majesty 13.04.2023 11:22

Вы можете сделать это, создав свой собственный 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 13.04.2023 11:22

Я понимаю @Majesty, в этом случае вы можете добавить его в метод createApplication, смотрите обновленный ответ.

piscator 13.04.2023 11:35

Я только что проверил ваш подход, добавив var_dump внутрь createApplication, и кажется, что этот метод также вызывается в каждом тестовом примере.

Majesty 13.04.2023 12:19

Я извиняюсь за то, что читал слишком быстро. В этом случае вы можете просто добавить статическую переменную $cacheCleared, запускать команды только тогда, когда она равна false, и установить для нее значение true после запуска команд.

piscator 13.04.2023 12:27

Статическая переменная не будет работать, каждый тест будет создавать другое приложение, и по этой же причине не работает createApplication.

Charlie 13.04.2023 14:08

Можно со статической переменной: stackoverflow.com/a/56086498/4593376. Другим решением было бы проверить, очищен ли кеш.

piscator 13.04.2023 15:21

@piscator Я думаю, вам следует читать более внимательно, а не просто копировать чей-то ответ, ответ, который вы опубликовали, имеет предварительное условие: если все ваши тесты буквально содержатся в одном классе, и в большинстве случаев ваши тесты не должны быть в одном классе.

Charlie 14.04.2023 06:10

Я тестировал статические переменные раньше, и поэтому я сказал, что это не сработает.

Charlie 14.04.2023 06:11

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

piscator 14.04.2023 09:41
Ответ принят как подходящий

Насколько мне известно, такого способа сделать это нет, потому что это не область юнит-тестов.

Модульные тесты предназначены для установки одинаковой среды для каждого теста, среда для всех тестов не входит в его обязанности.

Но вы все равно можете обойти это, создав пользовательскую команду для вызова 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 13.04.2023 12:35

@piscator У Laravel есть способы добавить аргументы в пользовательскую команду, вы можете прочитать документ Laravel, чтобы узнать, как это сделать. И это не проблема, которую задал этот пост.

Charlie 13.04.2023 13:37

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

Charlie 13.04.2023 13:38

В моем случае я пытаюсь создать данные для тестирования, перед началом теста я пробовал много способов, даже как вы ответили, используя createApplication() или setUp(), просто нет способа достичь того, чего я действительно хочу.

Charlie 13.04.2023 13:39

И в итоге я получил два решения: одно — это пользовательская команда, такая как ответ, который я опубликовал, другой способ — использовать .env.testing и создать тестовую базу данных для модульного теста.

Charlie 13.04.2023 13:40

Вам придется добавить все аргументы вручную в $this->call('test');

piscator 13.04.2023 15:13

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