Enter ExUnit callbacks and tags! ExUnit allows us to pass configuration data into and out of our tests by means of a dictionary, usually referred to as the "context". We can make good use of this context data by way of setup callbacks and tags. These are described well in the docs, and we'll lean on their examples for what we need to accomplish here.
So our test is currently testing TimestampWriter's ability to... ya know... write timestamps. And it works great, other than leaving the temp file sitting in the root of our project. While we could just add some code to our test to explicitly handle this, a better (and less-repetitious) approach is to modify our overall test case to do some setup and tear-down tasks for us automatically!
First, remove the junk file leftover at stats_yard/tstamp_write.test, and then we'll add a setup callback to our test case that will force our writes to happen in an appropriate directory:
- Line 2: We need to make sure our tests don't run in parallel since we're going to be switching directories. It sucks, but it's the nature of the beast
- Line 4: Define our setup callback, which will be executed prior to every test that is run
- Line 5: Check to see if our cd tag is present in the callback's current context dict. This is necessary because the same callback is executed for every test, but not every test will necessarily use this particular tag
- Line 6-7: Store the current directory and switch to the directory specified in the context
- Line 8: When the test exits (whether success or fail), switch back to our original directory
- Line 14: Our handy-dandy tag for the test that immediately follows
Let's see if it works!
- Line 23: Add a `tempfile` tag to our test to indicate that we're going to (attempt) to write a transient file
- Line 24: Make our test accept a dict argument called `context` (which will contain our `tempfile` key)
- Line 25: To keep things DRY, refer to the context's value for :tempfile instead of repeating the filename explicitly
- Line 9: When the test is done, check to see if a tempfile was specified for the test that's being set up
- Line 10: Make sure the tempfile actually got written, otherwise Line 11 will blow up
- Line 11: Call the "dirty" version of File.rm/1, just in case there are any weird permissions issues that prevent deletion of the file
So now we should be able to run our test, and see precisely zero remnants of it:
To wrap up, let's make our GenServer's module and API a bit more legit with a typespec and docstrings:
The @spec directive on Line 22 is simply a way to specify the types of the arguments our function can accept, an the type of value it will return. Easy stuff, and super helpful when we start looking into static analysis - it can help iron out a ton of bugs early on.
Next Time
Now that we've spent some time on some of the basics that we'll be seeing over and over again, the next post will get into more of the meat of our project and start doing stuff that's more interesting than writing a timestamp to a file. Specifically, we'll define the first iteration of our data format and figure out a way to represent that in code such that we can validate incoming requests for appropriate structure.
Until then, feel free to peruse the source for this post at: https://github.com/strofcon/stats-yard/tree/lets-build-4
No comments:
Post a Comment