Testing .net with IronRuby’s mini_rspec.rb
The IronRuby team has uses a couple facilities to test their own implementation of the Ruby language. simple_test.rb which resembles a Test::Unit type of framework with less baked in, and minispec by Brian Ford of the RubySpec project. (Thanks Charles for pointing out my error, sorry Brian for the wrong attribution). Minispec and RubySpec allow ruby implementations to test their compatibility among a common set of of specs produced by the RubySpec team. This allows the IronRuby team to run the same specs against Ruby, as well as run them directly through rbx.exe, the IronRuby interpreter. Once you get and compile IronRuby, you can see they have also created rake tasks to run the specs in a few scenarios. Here is the output of rake -T | grep spec.
rake rspec # run specs using Ruby - params are: class [method(…
rake spec # run specs - params are: class [method(s)] [reporter]
rake spec2 # run specs using IronRuby and Ruby - params are: c…
rake specs # run Ruby spec suite
So running rake spec from the command line will run all of the IronRuby specs through rbx. If you would like to take a look at all of these, the mini_spec framework is in %IronRubyRoot%\tests\ironruby\specs and all of the specs are in %IronRubyRoot%\tests\ironruby\specs\core.
One of the use cases I see IronRuby excelling at is writing unit tests. I’m a huge fan of RhinoMocks and NUnit, and am able to get a ton done with these tools, but after looking at testing in Ruby I’m always jealous of the tools the test centric Ruby community has at their disposal. There is no lack of elegant testing frameworks, tools, and practices on this side of the fence. Hopefully a good portion of them, if not all of them, will eventually make it over to IronRuby, but for now you can use these mini frameworks to test your .net code.
Disclaimer time, IronRuby is not even an alpha yet. Relying on these frameworks to do anything more then oooo look at me I’m testing .net with IronRuby demonstrations and practice is not suggested.
So on to the code. Let’s assume you are building a system that requires a person, and this person has a first and a last name. Imagine you have an class that represents that person that looks something like, or exactly like :
-
-
public class Person
-
{
-
public string FirstName { get; set; }
-
public string LastName { get; set; }
-
public string FullName
-
{
-
get { return string.Format("{0} {1}", FirstName, LastName); }
-
}
-
public int Age { get; set;}
-
public int AgeInDays
-
{
-
get { return Age*365; }
-
}
-
}
This complicated code MUST be tested. Below is some IronRuby code that works today that will test the class above. It looks like :
-
-
require ‘C:\projects\IronRuby\trunk\tests\ironruby\Specs\spec_helper’
-
require ‘c:\PathToMyDll\Person.dll‘
-
Nsp = NameSpaceThatTheAboveClassIsIn
-
-
describe ‘Nsp::Person’ do
-
-
before :each do
-
@person = Nsp::Person.new
-
end
-
-
it "should concatenate name" do
-
@person.first_name = "Bill"
-
@person.last_name = "Smith"
-
@person.full_name.to_str.should == "Bill Smith"
-
end
-
-
it "should be able to calculate age in days" do
-
@person.age = 1
-
@person.age_in_days.should == 365
-
end
-
end
That works today. Being a big fan of the spec syntax, I think this test reads very well, much less clutter then in a typical xUnit test.
Walking through the test, notice that we first bring in and alias the external resources we will need. Then we dive into a describe block that sets the initial context of the test. The describe method will either take a type or a string, but did not seem to like taking a .net type yet. Then we have a before filter that will be run before each test, setting initial state for the contexts below. Then we have a number of it blocks where specific tests are performed. Notice that once we have a Person instance, we can address it’s variables via Ruby conventions. My C# class has a FirstName property, but I can use the first_name convention in IronRuby, smooth.
Also of note, notice I had to call .to_str on @person.full_name. This is due to the fact that IronRuby string != CLR Strings as of yet. A recent thread on the mailing list reminds us all that the team will be fixing this later, but calling to_str will work.
Will I be doing this at work? Not yet, but the idea of using Ruby test tools to test my .net things is very appealing to me. Less cruft, mocking and stubbing should be a lot easier, and tools like AutoTest will change how I do TDD in .net if things come together as I am imagining.
You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.
February 21st, 2008 at 11:46 am
Hey Aaron, this is a great writeup! Thanks!
I’m very excited to use specs in Ruby to test my C# code. I hope we eventually see a CLR-based equivalent to Ola Bini’s JTestR library.
http://jtestr.codehaus.org/
February 21st, 2008 at 9:01 pm
I hate to nitpick, but minispec is the creation of Brian Ford, of the RubySpec project. Brian and the RubySpec contributors have been doing an amazing job writing specifications for the Ruby language and its core classes and libraries, and minispec has made it possible for even early implementations to run those specs. Rubinius uses RubySpec exclusively and we on the JRuby project include it as one of the many test suites we run.
February 21st, 2008 at 11:36 pm
Wow, great catch Charlie! I reread the article and it does sound like minispec was attributed to the IronRuby team. RubySpec is awesome and should definitely have more eyes on it. I feel bad for skimming over that earlier.
February 22nd, 2008 at 5:52 am
Charles : Not nitpicking at all. Thank you very much for pointing out my error. I will correct the post now.
Mike : Something like jtestr for .net things would be fantastic. I’m really excited to see where we can go with testing in IronRuby.