Wednesday, May 11, 2016

Let's Build Something: Elixir, Part 5b - Testing Data Validation and Logging

Let's wrap up this installment by writing some unit tests to safeguard us against bad changes to our data validation code!

First we'll put together a couple of tests to ensure that validation and invalidation are working correctly:


Let's see how we did:


Well, it certainly worked, but it's a bit clunky. Two things stand out:
  1. We should probably test multiple invalid DataPoints, since there are multiple guards that we want to make sure we got right. 
  2. We probably don't want those log messages showing up in the test output. We likely want to try and capture those to ensure that we are indeed logging appropriately, without cluttering the output of the test run.
So let's do that! First up, let's add some more bad DataPoint structs to test. We'll switch to using a list instead of individually-named structs for our tests, and we'll also do the same for the valid DataPoints - just in case we decide to test multiple ways there. Consistency FTW!


And the run:


Cool! We made our logging problem even worse, though. Let's take care of that. To make this work, we're going to use ExUnit's capture_log/2 to capture the output from Logger, spit out by our DataPoint module:


I inserted a small bug into the test for valid DataPoints - do you see it? No? It's pretty subtle, no worries. I told capture_log/2 that I'm expecting a Logger message with level :info, but our validation function is actually logging valid structs as :debug messages. Let's see how this works out:


So capture_log/2 captures the log event, but swallows it and the assertion fails since the level was mis-matched. Handy!

Switch the valid capture_log/2 call back to :debug and we're good to go:


(Note: I'm not sure yet how to make it stop complaining about unused variables here. They're certainly used, so I'm not sure why it's not happy about my use. I'll dig into that and iron it out in a later commit.)
Shout-out to DNNX for pointing out the problem with the unused variables in the DataPoint tests!  I've also updated the gist in this post to reflect his change. Check out his pull request for an explanation of what was happening here. Many thanks Viktar!

Next Time

We'll continue next time by introducing a worker pool that we can use to distribute our data validation workload over, and start sketching out how the write path will look when we start persisting data to disk.
Until then, feel free to peruse this post's code on Github at https://github.com/strofcon/stats-yard/tree/lets-build-5