Any ruby developer knows about the interactive ruby shell or in short irb and I am quite sure they use it everyday for quickly testing little scripts out. And Rails offers its own console which is basically irb with rails framework loaded with a valid database connection for performing quick tests. Now, in order to make it easy on your eyes one can change the default output of activerecords in console. But the question remains how? Well, I found a gem called hirb which simply does that for you. It is quite easy to install and configure and it improves the overall formatting by leaps and bounds.
It is only when one has to muck about with other mocking libraries one realises how cool rspec_rails is? It bascially provides you so much “rails” functionality out of the box that mocking and stubbing feels like a walk in the park. I have been trying some other mocking libraries and just can’t get my head around the whole mocking and stubbing thing. Anyways, I will keep trying and hopefully post.
I have moved away from fixtures and there is only one reason for it. factory_girl is an awesome piece of functionality the gives one the flexibility to easily define the data to use in tests and for populating the database with dummy data. However, I must add that I am also using Populator and Faker gems along with factory_girl to populate the database with dummy data but I will discuss it some other day.
Now, cucumber is the BDD library that allows one to write the features first. The features are in plain English and any client-manager can understand them. However, there was quite a debate few weeks ago over this whole issue of - “Who lets their client managers write stories?”. Follow the link if you are interested and read the comments. Anyways, I have been trying this out recently and I must say after an initial steep learning curve I can see the benefits. You just define the functionality from a user’s perspective and it makes the development a tad longer yet easier.
Now, using factory_girl from within rspec is easy but how can I make sure that the data is there before I run my cucumber features. Because in order to test a feature like a “admin should be able to delete a user” there must be a user in the system otherwise how could it be tested? Well, here’s the solution to it.
Problem: Create test data before the cucumber features.
In order to create an instance of a model object we can use one of the following depending on the situation:
Now, to make sure we create all the factories that we have defined already we need to get a list of all the defined factories somehow. And we need this list before we run the cucumber features. So, we simply add the following code to env.rb (cucumber’s config file) and voila!
Before do
require 'factory_girl'
Dir.glob(File.join(File.dirname(__FILE__), '../../spec/factories/*.rb')).each {|f| require f }
Factory.factories.keys.each {|factory| Factory(factory) }
end
You would ask why does this work? Well, let us see what does the define method do. The same method that we use to define a factory. Here’s the code inside the define method*:
# File 'lib/factory_girl/factory.rb', line 48
def self.define (name, options = {})
instance = Factory.new(name, options)
yield(instance)
if parent = options.delete(:parent)
instance.inherit_from(Factory.factory_by_name(parent))
end
self.factories[instance.factory_name] = instance
end
The last line in the method is basically adding the name of the created factory to the factories class variable and that’s the variable I use to get hold of these defined factories.
I think factory_girl has since changed its internal code. I am assuming it has since I tried using this code with Rails3 and cucumber-0.9.2 and cucumber-rails-0.3.2, but the features did not run at all. So, now if you wish to use factory_girl with cucumber add this in env.rb file instead:
Before do
require 'factory_girl'
Dir.glob(File.join(File.dirname(__FILE__), '../../spec/factories/*.rb')).each {|f| require f }
end
So, what I am simply doing now is building the factories but not actually creating them and now you can create all your factories in the step_definition files. I think this is a better way of using factory_girl with cucumber.
Isn’t Google Wave an extended, better designed and developed version of Google Groups and Google will slowly and shrewdly phase it out? The reason I say that is becuase I have recently signed up for RubyLearning Wave Group and it gives me a feeling that it has been built on top of the same concept as Google groups. How else can one explain the lack of spam management and clunky interface on Google groups?
Now, we all know that Google groups is terrible considering the Web 2.0 standards atleast. I know you would doubt my credibility and therfore you should read this article from John Resig (the Javascript Ninja and the creator of JQuery). I have been managing the Ruby Shoes group for quite some time now and what surprises me is that Google somehow has forgotten to implement the Gmail’s “spam controlling” strategy on Google groups.
Anyways, we will see what happens in the future but as it stands Ruby Shoes group has since moved to librelist and it has worked out well. Lifehacker has done a really nice post on some Google Wave “not so obvious” features.
I got hold of this great article that lists a lot of questions asked in Google interviews and honestly speaking I do not think with my present knowledge I will ever pass an interview there. I guess if I knew a bit more about algorithms I might have a chance. Therefore, I am going to start reading Donald Knuth’s - The Art of Computer Programming - Sorting and Searching book. I will see how it goes. Apparently, it is too complicated to understand and make sense of.
Nah I am just kidding who reads books now days. It is all about finding some tutorials on the internet and hacking things together. Well, I had the same opinion few months ago and one day I started reading a BDD book and really it makes a huge difference. And I am talking about actually reading and understanding and running the code and amending and making changes to the code and ensure you understand the underlying behaviour of a language or a library. Anyways, I am going off topic now.