Ramaze uses and encourages BDD (Behaviour Driven Development). Ramaze itself is tested using Bacon and supports it out of the box, it however isn't limited to just Bacon.
One might wonder why to bother with writing tests. The answer to this is quite simple: stability. Manually testing an application works on a very basic level but there are various issues that will arise once your application grows. The two biggest issues are human errors and repeatability. Especially the latter becomes an issue when your development team grows in size, while the initial developer may be willing to manually test every feature every time a change has been made others might not. Even worse, there's a chance they won't test their code at all and assume it's production ready because on their setup.
Writing tests that can be executed using a single command (or automatically) makes your life a lot easier as you no longer have to worry about any of these issues (assuming people actually write tests). Whenever somebody commits code they write a test and you can easily verify if it works on different setups by simply running said test.
When writing Ruby code you can pick from a large collection of testing libraries such as Bacon and Rspec for general tests, SimpleCov for code coverage and Capybara for testing form based actions and the like. Of course the list doesn't stop here, there's simply too much to discuss everything.
Bacon is a small and lightweight Rspec clone that's used by Ramaze and Innate and is the recommended tool to use. Each bacon test consists out of at least two bits: a "describe" block and an "it" (or "should") block. The describe block can be seen as a group of multiple it/should blocks. In most cases these blocks are used to specify the name of a class, module, etc. The it/should blocks are used for individual tests.
Lets take a look at a simple block of code:
class Person attr_accessor :name def initialize(name = nil) @name = name end end
Using Bacon we can test this code as following:
require 'bacon' describe 'Person' do should 'respond to #name' do person = Person.new person.respond_to?(:name).should == true person.respond_to?(:name=).should == true end should 'set the name in the constructor' do person = Person.new('Matz') person.name.should == 'Matz' end should 'set the name using #name=' do person = Person.new person.name = 'Matz' person.name.should == 'Matz' end end
For more information on the syntax of Bacon and other information see the Bacon Github project.
Bacon With Ramaze
Ramaze makes it easy to test your code using Bacon by providing you with a small helper file. This file can be loaded as following:
This file adds two bacon contexts (rack_test and webrat), configures Ramaze to only show error messages and adds a few helper methods.
Bacon and Rack::Test
In order to test Ramaze specific code you'll need to use a tool that's capable of mocking Rack requests or execute this request in a different way (e.g. using Selenium). Rack::Test (gem install rack-test) makes it possible to test your Rack based (and thus Ramaze) applications without having to use a webbrowser.
Ramaze makes it easy to use Rack::Test by defining a special bacon context:
"rack_test". This context can be used by calling
inside your describe block:
describe 'Using Rack::Test' do behaves_like :rack_test end
Once loaded you can execute HTTP requests using methods such as
describe 'Using Rack::Test' do behaves_like :rack_test should 'display the homepage' do get('/').body.should == 'Hello, Rack::Test!' end end
More information about Rack::Test can be found on the Github page of Rack::Test.
In order to use Capybara you must first install it:
$ gem install capybara
Once installed you'll have to configure Capybara so it knows how to use your Ramaze application. Depending on the testing Gem you're using you'll also have to configure said Gem, for this guide it's assumed that you're using Bacon.
First you should load and configure Capybara:
require 'capybara' require 'capybara/dsl' require 'bacon' # Tells Capybara which driver to use and where to find your application. # Without this Capybara will not work properly. Capybara.configure do |config| config.default_driver = :rack_test config.app = Ramaze.middleware end
Next you'll have to set up a context for Bacon:
shared :capybara do Ramaze.setup_dependencies extend Capybara::DSL end
Last but not least, make sure Ramaze knows about your root directories and set your mode:
Ramaze..roots << 'path/to/spec/directory' Ramaze..mode = :spec
Once all of this has been done you can start using Capybara. A simple example of this is the following:
class MainController < Ramaze::Controller map '/' def index return 'Hello, Ramaze!' end def redirect_request redirect(MainController.r(:index)) end end describe 'Testing Ramaze' do behaves_like :capybara it 'Go to the homepage' do visit '/' page.has_content?('Hello, Ramaze!').should == true end it 'Follow redirects' do visit '/redirect_request' page.current_path.should == '/index' page.has_content?('Hello, Ramaze!').should == true end end
For more information on how to use Capybara with other testing tools, how to use the syntax and so on you should resort to the Capybara Github page.
Code Coverage using SimpleCov
To test the Ramaze application tests coverage, you can use a tool like SimpleCov. SimpleCov requires minimal effort to get integrated, start by installing the gem:
gem install simplecov
In order to actually measure your code coverage you'll have to tell SimpleCov a bit about your application. This is done by loading Simplecov and starting it before loading all your tests. This can be done by using the following code:
require 'simplecov' SimpleCov.start # Load the existing files Dir.glob('spec/*.rb').each do |spec_file| unless File.basename(spec_file) == 'init.rb' require File.expand_path(spec_file) end end
In order to run the file you'd simply invoke the following:
Upon success SimpleCov will create a new directory
coverage with the
results. You can point your browser to the index.html file inside that directory
to view the results.
For more information on using Simplecov see the Github project.