Tuesday, November 24, 2015

Testing a New Artisan command in Laravel 5.1

It took me quite a while to figure this out today (and for sure there may be a better way), but there didn't seem to be a well-documented way to test Laravel 5.1 Artisan commands. The main reason that I want to do this is to be able to run some simple commands directly in an Artisan command without writing another class just to essentially act as a test harness. In the case I was working on, I'm adding a field to a database table that needs to be populated with an initial attribute in every row for ElasticSearch. This will normally happen when a record is upserted, but initially it'll run once for each row in a loop as part of a multi-system update. I thought I'd run it as an Artisan command, although realistically it'd be better run as a queue-able job.

I spent some time with Laracasts but the TDD tests were 1) based on Codeception (nice, but not what I wanted) and 2) were for Laravel 4. Directly using the Symfony console test methodology doesn't work with Laravel's IoC container in Laravel 5.1. Even the Laravel foundation tests don't specifically test each of the Artisan console commands. At least I couldn't find anything, although ultimately it was the way that Laravel instantiates Artisan that gave me a clue.

You can run an Artisan command in your tests, but what I really wanted to do was check the output to the terminal, which means capturing stdout while running a command, which the test-native Artisan command doesn't support.

In any event, this works well, and displays both ways of running an Artisan command in a test:

A blog post every couple of years seems to be about the right frequency. No?