In past posts I have talked a bit about behavior testing. I honestly feel
like this is the best way to clearly articulate across functional teams, namely
product, quality assurance and development, the requirements and expected behaviors
a software system should obey. Up until last week I had always maintained that
unit tests are there for coverage, and behavior tests are there to make the
company happy we are performing as expected with our software systems. I mean
it can’t possibly be practical to get real server code coverage from a consumer,
or external testing solution, right…
Golang Coverage
Ever wonder how go test -cover gives you your code’s coverage? Well, under
the hood, go test -cover actually compiles your executable, but before it
compiles the code, the cover tool actually re-writes your code with various
telemetry needed. An excellent primer can be found here.
Armed with this story, I set out on some experimentation to see if it was possible
to actually see a coverage report from the copious volumes of behavior testing
the company has been amassing. My first inkling is to see if there was a way to
generate a static executable with all of the coverage magic built into it. Turns
out that is really easy, as seen below(and on this gist):
This is great. Now lets figure out how we can wrap our main() function in a
test so we can make a running http server that will collect this code coverage
telemetry. Below is the main.go I have created to accomplish this, with comments
inline explaining what is going on.
The Test!
Armed with the above design, you can already see what the test will look like,
basically a “TestMain” function that kicks off runMain(). The normal
go build command will never run runMain() and thereby not setup the
deathblow endpoint that kills the service. Below is our super easy test:
*
Pretty simple! Our new commands to build a coverage enabled executable are as follows:
Hopefully you can impress your local QA peeps by giving them code coverage for
all of your external testing! Have fun!