Настройка и тестирование планирования задач Laravel
окружающая среда
Фреймворк Laravel Версия : 5.1.45 (LTS)
версия PHP : 5.6.1
описание
Я пытаюсь запустить команду каждые 1 минуту с помощью Laravel Планирование Задач.
попытка
я добавил эту строку в файл вкладки cron
* * * * * php artisan schedule:run >> /dev/null 2>&1
вот мой / app / консоль / ядро.в PHP
<?php
namespace AppConsole;
use IlluminateConsoleSchedulingSchedule;
use IlluminateFoundationConsoleKernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
AppConsoleCommandsInspire::class,
];
/**
* Define the application's command schedule.
*
* @param IlluminateConsoleSchedulingSchedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('inspire')->hourly();
$schedule->command('echo "Happy New Year!" ')->everyMinute(); //<---- ADD HERE }
}
я добавил эту строку $schedule->command('echo "Happy New Year!" ')->everyMinute();
вопрос
как это проверить ?
как вызвать мое Эхо для отображения ?
откуда мне знать, если я не ошибаюсь ?
Я открываю для любых предложений в этот момент.
любые подсказки / предложения / помощь по этому вопросу будут высоко оценены !
3 ответов
command()
запускает команду ремесленника. То, что вы пытаетесь достичь - выдача команды ОС - выполняется exec('echo "Happy New Year!"')
тестирование зависит от того, что вы хотите проверить:
- работает ли планировщик (каждую минуту)?
в этом случае, вам не придется. Он тестируется в исходном рамочном коде.
- успешно ли выполняется команда?
Ну, вы можете вручную запустить php artisan schedule:run
и видим выход.
планировщик не производит никаких выходных данных по умолчанию (>> /dev/null 2>&1
). Однако вы можете перенаправить вывод запущенных скриптов в любой файл, связав writeOutputTo()
или appendOutputTo()
(https://laravel.com/docs/5.1/scheduling#task-output).
для более сложной логики вместо этого напишите консольную команду (https://laravel.com/docs/5.1/artisan#writing-commands) и использовать command()
- таким образом, вы можете написать хороший, проверяемых код.
Если вы хотите модульное тестирование планирования событий, вы можете использовать этот пример. Он основан на команде inspire по умолчанию:
public function testIsAvailableInTheScheduler()
{
/** @var \Illuminate\Console\Scheduling\Schedule $schedule */
$schedule = app()->make(\Illuminate\Console\Scheduling\Schedule::class);
$events = collect($schedule->events())->filter(function (\Illuminate\Console\Scheduling\Event $event) {
return stripos($event->command, 'YourCommandHere');
});
if ($events->count() == 0) {
$this->fail('No events found');
}
$events->each(function (\Illuminate\Console\Scheduling\Event $event) {
// This example is for hourly commands.
$this->assertEquals('0 * * * * *', $event->expression);
});
}
основываясь на ответе Михила, я использовал методы, содержащиеся в Illuminate\Console\Scheduling\Event
чтобы проверить, должно ли событие выполняться в течение заданной даты.
Я высмеял текущую дату, используя Carbon::setTestNow()
Так что любая логика на основе даты в when()
и skip()
фильтры будут вести себя, как ожидалось.
use Tests\TestCase;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Console\Scheduling\Event;
use Cron\CronExpression;
use Carbon\Carbon;
class ScheduleTest extends TestCase {
public function testCompanyFeedbackSchedule()
{
$event = $this->getCommandEvent('your-command-signature');
$test_date = Carbon::now()->startOfDay()->addHours(8);
for ($i=0; $i < 356; $i++) {
$test_date->addDay();
Carbon::setTestNow($test_date);
// Run the when() & skip() filters
$filters_pass = $event->filtersPass($this->app);
// Test that the Cron expression passes
$date_passes = $this->isEventDue($event);
$will_run = $filters_pass && $date_passes;
// Should only run on first friday of month
if ($test_date->format('l') === 'Friday' && $test_date->weekOfMonth === 1) {
$this->assertTrue($will_run, 'Task should run on '. $test_date->toDateTimeString());
} else {
$this->assertFalse($will_run, 'Task should not run on '. $test_date->toDateTimeString());
}
}
}
/**
* Get the event matching the given command signature from the scheduler
*
* @param string $command_signature
*
* @return Illuminate\Console\Scheduling\Event
*/
private function getCommandEvent($command_signature)
{
$schedule = app()->make(Schedule::class);
$event = collect($schedule->events())->first(function (Event $event) use ($command_signature) {
return stripos($event->command, $command_signature);
});
if (!$event) {
$this->fail('Event for '. $command_signature .' not found');
}
return $event;
}
/**
* Determine if the Cron expression passes.
*
* Copied from the protected method Illuminate\Console\Scheduling\Event@isEventDue
*
* @return bool
*/
private function isEventDue(Event $event)
{
$date = Carbon::now();
if ($event->timezone) {
$date->setTimezone($event->timezone);
}
return CronExpression::factory($event->expression)->isDue($date->toDateTimeString());
}
}