Script/test in the language your app is written in

Things I Believe is on my periodic reading list – maybe it should be on yours?

So the following intrigued me:

Use the same language for the little tools and scripts in your system too. There are few good reasons to drop down into bash or Python scripts, and some considerable disadvantages.

A modern programming language is the most expressive tool we have for describing all aspects of a system.

This means: write configuration as code, unless it absolutely, definitely has to change at runtime.

Also, write the specification of the system as executable code.

And, use code to describe the infrastructure of your system, in the same language as the rest of the code. Write code that interprets the description of your system to provision actual physical infrastructure.

At the risk of repeating myself: everything is code.

Corollary: if you’re writing JSON or YAML by hand, you’re doing it wrong. These are formats for the machines, not for humans to produce and consume. (Don’t despair though: most people do this, I do too, so you’re not alone! Let’s just try to aim for something better).

And then I read Why you shouldn’t use func main in Go.

And then I needed to set up a test harness where two gateway instances were needed to test rules that execute between gateways. In the past, I’ve been a big fan of envsetup.sh for starting up my test instances. However, after reading the above, it become obvious – why not write a Go program that fires up two GW instances. Matt’s pattern makes it really easy to do this. go run is a nice scripting environment …

If all parts of your system are abstracted as functions, it is very simple to stitch together a test harness that instantiates the entire system, runs tests, etc. And, since one program is watching all the instances, it is very easy to do something in one, and then look for a change in another.

When you do something like embed two instances of your GW code in a test harness, suddenly you find all the little hacks (like global variables). Reminds me another quote from “Things I believe”:

Write code that is exception safe and resource safe, always, even in contexts where you think it won’t matter. The code you wrote in a little ad-hoc script will inevitably find its way into more critical or long-running code.

Everything should be instantiated as types with embedded data (never globals), and all data/config needed should be passed in. This is a little verbose at times, but saves a lot of trouble later when your code goes places and does things you never originally envisioned.