I've always felt that getting up and running with a new web development project should be as easy as possible. A good example of this is a Rails app. As Ruby on Rails accomplishes a high degree of ease of use straight out of the box, this article will focus on setting up an automated testing environment and sprucing up your CSS with bootstrap-sass.

I'm going to assume that you already have the following items installed: Ruby on Rails and Git. You will need both of these before going further into this setup.

The Gemfile

The first thing we need to do is add all the necessary gems. The bootstrap-sass gem neatly encapsulates most of the configuration for us with a small config caveat that I will go into later. To get smooth automated testing up and running with Minitest we need a number of other gems.

Add the following to your Gemfile. Once added we need to run bundle install to install the newly added gems.

gem 'bootstrap-sass', '3.3.3'

group :test do
    gem 'minitest-reporters', '1.0.10'
    gem 'mini_backtrace', '0.1.3'
    gem 'libnotify', '0.9.1' # Optional notification plugin for linux
    gem 'guard', '2.11.1' # Guard task runner
    gem 'guard-minitest', '2.4.3' # Guard minitest support
    gem 'spring', '1.2.0' # Optional testing server for guard
end

With the gems now installed it's time to start configuring them with our environment. Let's first deal with our Bootstrap-sass configuration.

Bootstrap-sass

As I mentioned earlier, the gem will do most of the work for us. If you look at /app/assets/javascripts/application.js and /app/assets/stylesheets/application.css you should see some comments that say //= require bootstrap-sprockets. For our application.js file we can leave these alone as they will work as expected. However, with Sass files the problem with the comments is that not only does it include our new bootstrap-sass gem but they also load all .css or .scss files in the assets/stylesheets directory. This makes it problematic for spliting Sass files into partials as the order they are included isn't specific.

To fix this we need to remove all the comments from application.css. Also make sure that you rename the file to application.css.scss to use the sass file ending (or .sass if you like the indent version). Once the comments are removed and the file renamed we can now use Sass's built in @import statement to structure our files however we want. While we do lose the ability to automatically load all the stylesheets at once we are now able to load them with their partials in the proper order. It should look like the following code.

// We need to manually import the bootstrap-sass gem Sass files
@import "bootstrap-sprockets";
@import "bootstrap";

// Add your Sass files here or just write sass
@import "pages";

.red {
    color: red;
}

We now have a working system for including Sass files and partials in a specific order. Sass is excellent at compiling multiple @imports together so no need to worry about the site running slower. Additionally, since we used the gem it has the Bootstrap framework built-in which is awesome!

Minitest

There are a lot of different testing solutions for using Rails. You have Rspec, Cucumber, Test::Unit, and Minitest. Rspec is really powerful but can be quite tricky to get working right. Cucumber is great for its easy to read tests that could allow your clients to write the application specs as tests. For starting out though I would recommend Minitest because of how easy it is setup and also that it is the preferred unit testing framework packaged with Rails.

There are two gems from the Gemfile section that are associated with getting minitest looking sweet: minitest-reporters, and mini_backtrace. Minitest reporters adds hooks for better display output from tests. Mini backtrace add supports for backtrace cleaner to prevent really long error messages while running your test suite.

To setup minitest-reporters open your test_helper.rb file and add the following code above the line class ActiveSupport::TestCase.

    require "minitest/reporters"
    Minitest::Reporters.use!

Next mini_backtrace needs the following code added to it. This will suppress some messages regarding rvm in the console. You may need to adjust this depending on your Rails environment setup (rvm or rbenv).

    Rails.backtrace_cleaner.add_silencer { |line| line =~ /rvm/ }

Awesome! You can now run tests on your app with clean output using rake test. Of course manually running tests is so un-hip so let's setup our automated testing suite with Guard.

Automated testing: Guard

Guard is an awesome event handler for the command line. Built in native ruby it integrates well into the Rails workflow. Setting up Guard is pretty easy just run guard init minitest to create a basic Minitest Guardfile.

The Guardfile is similiar to gulp or grunt in that it watches for particular events to occur and then performs an action. Your Guardfile should looking something like the following code

guard :minitest,
  spring: false,
  all_on_start: false,
  all_after_pass: false do

  # with Minitest::Unit
  watch(%r{^test/(.*)\/?test_(.*)\.rb$})
  watch(%r{^lib/(.*/)?([^/]+)\.rb$})     { |m| "test/#{m[1]}test_#{m[2]}.rb" }
  watch(%r{^test/test_helper\.rb$})      { 'test' }

  # Rails 4
  watch(%r{^app/(.+)\.rb$})                               { |m| "test/#{m[1]}_test.rb" }
  watch(%r{^app/controllers/application_controller\.rb$}) { 'test/controllers' }
  watch(%r{^app/controllers/(.+)_controller\.rb$})        { |m| "test/integration/#{m[1]}_test.rb" }
  watch(%r{^app/views/(.+)_mailer/.+})                   { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
  watch(%r{^lib/(.+)\.rb$})                               { |m| "test/lib/#{m[1]}_test.rb" }
  watch(%r{^test/.+_test\.rb$})
  watch(%r{^test/test_helper\.rb$}) { 'test' }
end

Basically we have all the particular watched files within the guard block. These will essentially fire off your unit tests depending on which files are being modified. To start Guard just run guard in the terminal from your Rails project directory. It will take a few seconds and then should start polling for events. Super handy and cuts down on the time it takes to manually run unit tests. The only issue is that the test suite runs really, really slowly. This is where the Spring preloader gem comes in handy by reducing the execution time of your test suite.

Spring

Spring is a preloader meaning that your application assets will become loaded before your tests so that Guard doesn't need to re-build them everytime you run your test suite. The reduction in run time can be quite impressive from 5 seconds to almost instantaneously. Spring with Guard makes Test-Driven Development a dream. To setup Spring you first need to add Spring to your app's executables by running bundle exec spring binstub --all. Next make sure the Spring attribute is marked as true in your Guardfile.

    guard :minitest, spring: true, all_on_start: false, all_after_pass: true do

We now have all the basics of a proper automated testing environment setup. System notifications in the next section add another layer of convenience with testing.

Notifications

Having notifications from your test suite is just another way to increase your productivity by not having to pull up terminal every 5 seconds. Since I am using Linux the gem I choose was Libnotify to add notifications. There are a number of different system notifiers. To find out which one is available for your OS check out the system notifications faq page. This page also includes install instructions or further documentation pages.

Git

Lastly, is version control. It is recommended to follow the useful gitignore file located here for your programming language. Look at the ruby and rails sections for preferred ignored files. Additionally, since we are using Spring for preloading make sure to ignore spring files by adding /spring/*.pid to your .gitignore file. Here is a basic .gitignore file below

# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
#   git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*
!/log/.keep
/tmp

# Ignore Spring files.
/spring/*.pid

# Ignore secrets
config/secrets.yml

And there you have it! A fully functional Ruby on Rails environment utilizing the bootstrap front-end framework with sass, an automated testing suite with Guard, Minitest, Spring, and System notifications, and a ready to go Git setup. This is a great starting place for new Rails applications. Have a suggestion or comment? Leave me a comment below.

Join the conversation

comments powered by Disqus