135호. 라라벨 아티즌 명령어 스케줄 테스트하기 free

2020-04-30

라라벨 작업 스케줄링을 이용하면 여러 크론잡을 편리하게 관리할 수 있습니다. 라라벨 메뉴얼을 보면 버전관리도 되고, 스케줄 작업이 추가/변경/삭제 될 때마다 모든 서버에 반영하지 않아도 된다는 장점이 있다고 이야기하고 있는데요. 여기에 더해 테스트 코드를 작성할 수 있다는 장점도 있는 것 같아요.


실수하기 쉬운 스케줄 정의


최근에 작업 스케줄링을 활용하는 코드를 작성할 일이 있었는데요. 테스트 서버에 배포하고 다음 날 확인해보니 에러가 나고 실행이 안되어 있더라고요. 이유를 알고 보니 아티즌 명령어를 잘못 기입했던 겁니다. 리팩토링을 하는 과정에서 명령어 시그니처를 바꿨는데, 스케줄링 코드에는 깜빡하고 수정을 안해놨던 것이죠.


아티즌 명령어를 정의하는 코드와 스케줄링 코드는 다음과 같이 생겼기 때문에, 변수명이나 메서드명을 바꿀 때처럼 IDE가 찾아서 고쳐주는 기능의 혜택을 볼 수가 없습니다. 그래서 실수하기 좋죠.


// 아티즌 명령어 시그니처 정의
class SendEmails extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'email:send {user}';

// 스케줄 정의
$schedule->command('emails:send Taylor --force')->daily();

스케줄 테스트하기


다음은 스택오버플로에서 찾은 코드를 일부 수정하고 해설을 추가한 유닛 테스트 코드입니다. 이를 활용하면 스케줄이 제대로 설정되었는지 테스트할 수 있습니다.


public function testIsAvailableInTheScheduler()
{
// 컨테이너에서 Schedule 클래스 객체를 받아옵니다.
/** @var \Illuminate\Console\Scheduling\Schedule $schedule */
$schedule = app()->make(\Illuminate\Console\Scheduling\Schedule::class);

// Schedule 객체에서 events()를 호출해서 전체 스케줄을 받아와서 컬렉션으로 만든 후
// 이 중에서 여러분이 확인하고자 하는 커맨드를 실행하는 스케줄만 골라냅니다.
$events = collect($schedule->events())->filter(function (\Illuminate\Console\Scheduling\Event $event) {
return Str::endsWith($event->command, 'YourCommandHere');
});

// 아무 것도 찾아지지 않았으면 테스트를 실패로 선언하고 중단합니다.
if ($events->count() == 0) {
$this->fail('No events found');
}

// 스케줄이 원하는 주기로 설정되었는지 확인합니다.
$events->each(function (\Illuminate\Console\Scheduling\Event $event) {
// 매시간 실행하는 커맨드인 경우 아래와 같이 확인합니다.
$this->assertEquals('0 * * * * *', $event->expression);
});
}

하나의 커맨드를 여러가지 스케줄로 실행하는 등의 특이한 경우에는 위의 코드만으로는 부족하고 조금 수정해야할 필요는 있을 겁니다. 하지만 위 코드가 보여주는 기본적인 아이디어를 활용하면 충분히 상황에 맞는 테스트 코드를 짤 수 있을 거라 생각합니다.


그럼 오늘도 즐거운 라라벨 생활하세요~


이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.