Testing and Documenting a Rubygem

13th May 2013

In this post we're going to continue working on the gem we made in the previous tutorial, getting it ready for publication by adding tests with RSpec and documenting it using YARD.

Setting up RSpec

Before you make any gem public it's good practice to add a suite of tests – especially if you expect other people to be working on it and contributing back to your codebase.

There are a few different testing tools available for Ruby, but in this tutorial we're going to be using RSpec. If you're following along, install the gem with the following command:

$ sudo gem install rspec

As well as installing the RSpec gem on your local machine, we need to add it as a dependancy in our listless.gemspec file. Anyone who forks our gem should be running tests in a development environment (rather than production), so it makes sense to use the gem.add_development_dependency method here.

File: listless.gemspec
Gem::Specification.new do |gem|
  ...
  gem.add_dependency "htmlentities"
  gem.add_development_dependency "rspec"
end

Adding Tests

Learning the RSpec syntax is a whole tutorial in itself, so if you're not familiar with it I recommend browsing the introductions from David Chelimsky and Treehouse before reading on.

A common convention when using RSpec is to keep all your tests scripts contained in a directory named spec. We should also make sure that all the names of our test scripts end in _spec.rb, so that the RSpec executable knows that they contain tests that need to be run. Let's create the directory and a single file for holding our tests.

$ mkdir spec
$ touch spec/listless_spec.rb

Great stuff. We'll now open the empty listless_spec.rb file and add a couple of simple behavioral tests – one that checks the gem is transforming an Array into an HTML list, and another which checks that characters are being HTML encoded properly.

File: spec/listless_spec.rb
# -*- encoding: utf-8 -*-
require_relative '../lib/listless'

describe Listless do
  describe "#ul" do

    it "should create an unordered list" do
      Listless.ul(['foo', 'bar']).should eql "<ul><li>foo</li><li>bar</li></ul>"
    end

    it "should escape appropriate characters" do
      Listless.ul(['<élan>']).should match %r(&lt;&eacute;lan&gt;)
    end

  end
end

It's also worth pointing out the require_relative statement at the top of the code, which gives the tests access the main Listless module and allows them to run correctly.

We can execute our tests by running rspec from the terminal, passing in the name of the folder holding our test scripts.

$ rspec spec
..
Finished in 0.00696 seconds
2 examples, 0 failures

If the results look good and you get a pair of dots indicating that the two tests have passed, then now is a good time to commit the changes.

$ git add .
$ git commit -a -m 'add: behavior tests using rspec'

Complete the README

When we used Bundler to set up our gem in the previous tutorial, a boilerplate README.md was created. Arguably the most important piece of documentation for a gem, the content of the README acts as the homepage when we generate YARD documentation (in the next section), and is also used by Github and Bitbucket as the default landing page for a repository.

Let's complete this by filling in the description and usage sections, using Markdown for formatting.

File: README.md
## Listless

Listless is an example gem created for a series of blog posts about [how to make a rubygem](http://www.alexedwards.net/blog/how-to-make-a-rubygem), and not intended for production use.

It provides a helper method to convert a Ruby Array into a HMTL unordered list.

…

## Usage

Require the Gem:

    require 'listless'

### Creating unordered lists

You can create an unordered list from an Array using the `ul` method. For example:

    Listless.ul ['foo', 'bar']
    #=> "<ul><li>foo</li><li>bar</li></ul>"

Again, let's commit the changes.

$ git commit -a -m 'add: description and usage instructions'

Adding Documentation

Finally we're going to add some documentation using YARD. Unlike RDoc (another common documentation tool) YARD ships as a standalone gem which we'll first need to install.

$ sudo gem install yard

Documenting the gem is straightforward – you simply add a comment block before each method describing what it does. Although there's no set list of things a comment should include, it's generally a good idea to describe the arguments a method takes, its return values and any exceptions. Providing an example can also be useful.

To do this in a machine-readable way, YARD provides a number of tags to help markup your comment, like @params, @return, @raise and @example.

The official YARD Getting Started Guide is great, short read, and you can find a complete list of tags here.

Let's go ahead and document our lone public method.

File: lib/listless.rb
require "listless/version"
require "htmlentities"

module Listless
  extend self

  # Create a HTML unordered list from an array
  #
  # @param array [Array]
  # @return [String]
  #
  # @example
  #   Listless.ul ['foo', 'bar'] #=> "<ul><li>foo</li><li>bar</li></ul>"

  def ul(array)
    list = array.map { |x| tag(:li, escape(x)) }.join
    tag(:ul, list)
  end

  

end

And that's all there is too it, nice and easy. Now that we've added the YARD comments, we can automatically generate some nice HTML documentation for publication on the web. Run the following command in your gem directory.

$ yard doc

You should see a directory called doc being generated in the root folder of our gem. Open up doc\index.html in your browser and take a look around – don't miss the Method List link in the top right to see how the comment we just added is being rendered. Pretty neat, hey?

As a side note, because this HTML documentation is automatically generated based on other files in our gem, it doesn't make sense to include it in version control. Open up the hidden .gitignore file in the gem directory and check that it includes a doc/ line, instructing Git to ignore the contents.

Let's commit our changes.

$ git commit -a -m 'add: YARD documentation for public methods'

As a second side note, if you rebuild and reinstall the gem on your local machine, you can also view the documentation from the terminal using the ri command.

$ gem build listless.gemspec
$ sudo gem install --local listless-0.0.1.gem
$ ri Listless.ul

Wrapup

Our simple gem is now tested, documented, and ready to share with the outside world. In the final tutorial we'll look at how to publish our gem on Rubygems.org, handle changes and versioning of our gem in a sensible way, and also add an executable so we can use our gem on the command line, outside of IRB.

You can find the full source code for this gem on Github.

Filed under: ruby, tutorial