Post

Testing Go with Ruby

Earlier this month I started building a Git clone in Go as a way to learn more about the language and see how it feels working with it. All was going well and untested, until I faced some weird issue in the way blobs were created. Of course, I didn’t know what the issue was back then, I just knew my time machine command was kinda broken. So I thought writing tests would be a good way to catch these errors in time. I tried writing some tests in Go for a couple of core files, but to be honest I didn’t really think it would be a viable approach for my Gogot. So I decided to use RSpec instead of the default Go’s testing library. Why RSpec? Glad I asked:

  1. De facto standard-setter in behavior-driven testing. The describe/context/it blocks have been copied by libraries in languages other than Ruby, because it’s easy to understand and to describe different scenarios with it. Go (afaik) lacks something similar, and I highly doubt it will get something similar in the foreseeable future.

  2. I know Rspec better than [insert testing framework here]. It is a spoon that I have been sharpening for 5 years now, and it doesn’t seem like the right time to get rid of it yet.

  3. I can execute shell commands in Ruby using backticks, and it makes writing tests for Gogot as a shell utility really straightforward.

So to make it a bit fancier, I’m using a Dockerfile to build Gogot inside a Go container, and then I’m “installing” the compiled ‘gogot’ onto a new Ruby container which contains only the test code, where I’m finally running all the tests through the ‘rspec’ command. I added a shell script that will build the container and will run the tests, and if everything goes right the whole output should fit inside a terminal’s screen :D

light-side-better-than-dark-side

For a closer look at the tests, here’s writing the scenario “Adding files without a path prints usage information” in code, following the good practices of Better Specs. The commands inside the backticks are executed “for real”, and I have to make sure to clean up after every example (test) that I run. Since this is executed inside a container, the world outside it in not affected.

testing

Besides all that testing suite and connecting it to Travis CI, I have been working on a ‘status’ command that looks like this (ignore the “nothing to commit message” at the end, it’s still work in progress):

gogot status

Looking at the languages section of the Github repo, I’m thinking this is one language away of becoming a chimera of bad code in more languages than you need, but I feel this approach is better for testing it as a real tool. Writing the tests this way helped me find more than enough issues in the code and also refactor here and there.

This post is licensed under CC BY 4.0 by the author.