Testing Logs in Elixir

Dec 4, 2020

I work on an app that logs a bunch of data. Typically, I wouldn’t test logging, but we have some issues where bad pattern matching is causing some 500 errors because it can’t handle the responses we are getting.

After some poking around, I ended up on a cool way in ExUnit to test for specific log messages. But there is one major issue that tripped me u[]

The module is ExUnit.CaptureLog and allows you to pass in a function and check that the log has the message you expect.

On the surface, it’s pretty simple. assert capture_log(fn -> Logger.error(msg) end) =~ msg That will assert that Logger.error(msg) actually logs msg.

Just replace Logger.error(msg) with the function that performs the logging and your all set. Mine looks like this because I know if it got to logging something that contains webhook_received, the code executed properly: assert capture_log(fn -> Persistence.MessageQueue.log_message(event_data) end) =~ "webhook_received"

Unfortunately, I was getting a success message when it clearly wasn’t passing. I really don’t know why. What I do know is that the log setting in config directly effects this, and defaults to :warn. By setting that to :info, messages start to flow through when testing, and the assertions start to actually pass/fail accurately.

You may have already noticed that setting the log messages to info makes for a really noisy test suite. But, there is a way around that also.

I haven’t gotten to it yet, but @tag :capture_log will allow you to define which tests should report logs and which ones shouldn’t.

This forum thread was super helpful.

If you would like to be notified the next time I write something, you can subscribe with your choice of RSS or Email.

I promise not to spam you and you can unsubscribe at anytime.

Also, here are some other items you might like longer longer:

or go see everything in the archive.