Hi, I'm Blake Williams

I'm a full-stack developer living in Boston, MA.

*full-stack meaning I really enjoy writing Rails, Elixir, React (Native), and sometimes HTML & (S)CSS.

May 2013
#ruby #tdd

Developing Gems with TDD and Minitest: Part 1

If you've ever used Ruby you'd know that Gems are fundamental to any Ruby project. Despite Gems being so important it can be intimidating to write your own gem let alone how you should test them. This will take us through writing and testing a very basic static blog generator.

First we need to get started by installing bundler with gem install bundler (if you don't already have it). Then we use Bundler to create our initial gem layout.

bundle gem mark

This will create our initial gem structure, initialize a git repository for us, give us a gemspec template, and set up some very helpful rake tasks for building and releasing gems.

Let's take a look at mark.gemspec first. We can see that bundler has already filled in a lot of information for us, but we need to add a description, a summary, and our dependencies before we can do anything with our gem.

Set both the description and summary to "Simple static site generator." and add the following below the other add_development_dependency lines.

spec.add_development_dependency "minitest", "~> 4.7.3"

spec.add_dependency 'tilt'
spec.add_dependency 'redcarpet'

We're adding the Minitest gem because that's what we'll use to test our app. We include Tilt for an easy way to render our templates and Redcarpet to render markdown for us. Now just run a quick bundle install and everything should be good to go.

Before we make our initial commit to git we want to setup Minitest and add our test tasks to rake. Create a new directory in the root of our gem called test and then create file called test_helper.rb inside of the test folder with the following content.

require 'mark'
require 'minitest/unit'
require 'minitest/autorun'
require 'minitest/pride'

Here's what's going on with our require calls:

  • require 'mark' is requiring our gem, so we can test it.
  • require 'minitest/unit' requires the unit test side of Minitest.
  • require 'minitest/autorun' actually runs all of our tests.
  • require 'minitest/pride' makes our tests pretty because aesthetics matter!

Now that we have our test directory setup, we need to add our rake tasks to our Rakefile which is incredibly simple.

require 'rake/testtask'

Rake::TestTask.new do |t|
  t.libs << 'test'
  t.pattern = "test/*_test.rb"
end

Just a simple explanation of what we're doing, Rake provides us with Rake::TestTask which does exactly what we want, runs our tests when we type rake test. We just provide it a block that says add the test directory to our libs for our test helper and that the pattern it should look for in tests is any file in the test directory that ends in _test.rb.

Now that we have everything in place we can finally add all of our files with git add . then make our initial commit with git commit -m "Initial commit".