model_stubbing for the common man (or woman)

Uncategorized — jeremy @ 10:42 pm

UPDATE: Fixed a few errors that Rick pointed out.  Oops! :)

So, I wrote a while ago about model_stubbing and why it was my favorite way to replace fixtures. A few people wrote me asking questions about model_stubbing, so I figured I’d write up a tutorial (notwithstanding the fact that I said “I’m writing a tutorial on model_stubbing” in the last post…).

Philosophy

The model_stubbing plugin lets you do just that: stub models. You can setup model stubs that contain data that you specify. Of course, there are already a lot of solutions out there for this problem (one of them built into Rails actually), but model_stubbing differs from these other solutions in this area in three primary ways.

First, it creates real instances of model objects (unlike most stub libs). Creating real instances means that it goes through all your lifecycle methods, callbacks, etc. rather than simply stubbing out the readers on fake objects. This approach gives you the advantage of being able to test your code in a “real” object ecosystem and do effective functional/integration testing with your models with stubbed data.

Second, it lets you have multiple stubs for the same model and use them naturally (unlike most factories). This is where model_stubbing really exploits the good parts of the factory approach and the fixture approach. You get real objects while being able to address them with something as simple as users(:jeremy) (I’ll show you how this works in just a bit…).

Third, it uses straight Ruby, so it’s easy to add your own logic or wrap helpers into it (unlike fixtures). You can easily write macros to do things like easily stub an STI table (e.g., rather than stubbing a User model and filling in type, permissions, etc. etc., you could simply make a moderator_stub method or some such to generate all that for you).

Getting model_stubbing

You can grab model_stubbing from Rick’s Github here: http://github.com/technoweenie/model_stubbing/tree/master

Specifying models and stubs

Here’s a very basic model stub:

# RSpec describe block...works in other testing tools, too!
describe "A fancy controller" do
  define_models do
    model Site do
      stub :title => “My Company”, :private => false
    end
  end

  it “should do something magical…” do
    # blah blah blah
  end
end

You use the define_models method right inside your testing context (describe blocks if you’re on RSpec). You’ll notice that there are three primary methods in use here: define_models, model, and stub. The define_models method basically says, “Hey, I’m going to be shoving stubs in this block. kthxbai.” It does a little more than that, but I’ll discuss exactly what later on.

Next, the model method lets you specify which model class you’re going to be generating stubs for. So, in this example, we’re generating stubs for our Site model class. You can sub any class in there, but it can only be one class at a time.

Finally, we drill down to the stub method, which actually creates a stub. In this case, we’re making a default stub for the Site class with the title “My Company” and the private attribute set to false. Now you can address this stub in code by doing sites(:default). You can create subsequent stubs like so…

define_models do
  model Site do
    stub :title => "My Company", :private => false
    stub :entp, :title => "entp Company HQ", :private => false
    stub :caboose, :title => "Caboo.se", :private => true
  end
end

And address by the name you give them as the first argument (in this case, something like sites(:entp) or sites(:caboose)).

Inheriting stubs

One of the great time saving features of model_stubbing is that it lets you inherit attributes from previous stubs. So, for example, if we have a set of stubs for blogs like this:

define_models do
  model Blog do
    stub :name => "OMGBLOGLOL!!", :rss => true, :atom => true, :html => true, :scrape => true
    stub :fireball, :name => "Daring Fireball", :rss => true, :atom => true, :html => true, :scrape => true
    stub :techcrunch, :name => "TechCrunch", :rss => true, :atom => false, :html => true, :scrape => true
    stub :hoth, :name => "entp Hoth", :rss => true, :atom => false, :html => true, :scrape => true
  end
end

We could refactor them to be much shorter like so:

define_models do
  model Blog do
    stub :name => "OMGBLOGLOL!!", :rss => true, :atom => true, :html => true, :scrape => true
    stub :fireball, :name => "Daring Fireball"
    stub :techcrunch, :name => "TechCrunch", :atom => false
    stub :hoth, :name => "entp Hoth"
  end
end

The stubs inherit their attributes from the stubs above them. So blogs(:fireball) has the same attributes as the :default stub unless it changes something (e.g., its name in this case), and any subsequent stub will have those same attributes unless one is changed (as we did with the :techcrunch stub’s :atom attribute, which will then pass its changed attributes down to subsequent stubs).  So, in this case, the :fireball blog has the same attribtues as :default with the exception of name.

Associations and other stuff

Specifying associations is really, really simple in model_stubbing. You simply refer to a stub on the belongs_to side of an association (since that’s the side that the association_id has to be filled in on). So, for example, if we had a stub for Authors that belong to our above Blog models, we could do something like this:
define_models do
  model Author do
    stub :name => "Jeremy", :blog => blogs(:default)
    stub :gruber, :name => "John", :blog => blogs(:fireball)
  end
end

You simply refer to them as you would in normal testing code (previously there was an all_stubs method, but that’s gone now!).

Breaking stubs up

So far I’ve only shown you how to embed the stubs in a describe block, but you can also split them out into their own file and require it into your specs or spec helper. At that point you simply need to call define_models to get your stubs in place.

describe "A fancy controller" do
  define_models

  it "should do something magical..." do
    # blah blah blah
  end
end

This call will load all the default stubs. I say “default” because you can also namespace your stubs to an extent. So, if you need different stubs for different contexts (very useful for only loading the stubs you need to test a certain portion of a system), then you can change your define_models call slightly.

ModelStubbing.define_models :permissions do
  model User do
    stub :name => "Jeremy", :login => "jeremy", :password => "merph"
  end

  model Permission do
    stub :object => 'Blog', :permission => 'edit', :user => user(:default)
  end
end

Using this form, you can name a set of stubs, giving them a label you can refer to later. Then you can change your define_models call in your specs to something like:

describe "Your protected controller" do
  define_models :permissions

  it "should keep out the hoi polloi." do
    # blah blah blah
  end
end

Stupid stubbing tricks!

The final section of this post is just a grab bag of random techniques I’ve picked up from working with model_stubbing.

Generating random data for stubs

The cool thing about this using Ruby is that you can use other Ruby code with it, like the Faker gem from Ben Curtis. Using Faker, you can generate random stubs easily:

ModelStubbing.define_models do
  model User do
    stub :name => Faker::Name.name, :email => Faker::Internet.email, :admin => false
    stub :admin, :admin => true
 end
end

You can find out more about the Faker gem over at the docs here.

(OK, really it’s just one trick but I’ll more here later…I promise! :))

on community

Ruby, Uncategorized — jeremy @ 7:12 am

Don’t let Zed Shaw fool you.  There is a community here, and it’s different than anything I’ve seen in any other programming language.

I’ve been getting a lot of feedback about the “free” cost of Hoedown ‘09.  I appreciate the sentiment, I really do.  I know to a lot of people putting on something like this for free is crazy, throws off the market for conferences, lowers the perceived value of the conference, will cause a lot of headaches for me, may cause the world to explode, and pandas may cry because of its existence.  But I’m OK with all that (except maybe that last one).  So, since I’ve gotten a lot of e-mail about it, I’m going to lay the deal out. :)

If you know me, I don’t care about money very much.  I give away my book for free.  I let so many people into the Hoedown for free this year it was ridiculous.  I give away most of the code that I write outside of work.  I’ll typically give you just about anything.  I don’t meter my days out hour by hour by how much money I can make.  I prefer to enjoy life and let money take care of itself.  I have other, faith-oriented reasons, for this attitude, but this post isn’t about that (but if you’re interested in it for whatever reason, I’d be glad to share).

If you really have to look at conferences from a business perspective, consider this: there’s more to “value” than money.  There’s business value.  There’s community good will.  There’s personal value.  There’s enrichment.  These are things that stick with people longer than a fair priced conference.  Things that I personally value more than money.

Even further, perceived value is sort of stupid unless it’s a product.  If I charged $2,000, that doesn’t make people think that the Hoedown is more awesome than RailsConf or something.  There may be 2-3 people who think that, but that’s just stupid.  Products are about the only realm where “perceived value” is a workable metric, and even then it’s sketchy at best (and only really works on directly comparable products that have no other distinguishing qualities).

But I’m not doing it for business.  It’s a more personal journey for me than that.

OK, so, communities exist by the sole contribution of its members, right?  The Ruby community wouldn’t exist if people didn’t contribute to Ruby core, Rails wouldn’t exist without the contributions of people, the Ruby book “community” wouldn’t exist without authors, and so on.  People have to contribute.  I want to be one of those people, and I want to do it in an unfettered manner.  I realized this year that I was charging money for something I didn’t want to charge money for.  The same reason I don’t charge money for my book (I want to give something back to a community that I’m passionate about) is the same reason I don’t want to charge for the Hoedown.  

I don’t want us to be Java.  I don’t want some vendor dictating when and where our conferences are, the direction of our open source projects, the goings-on in our community.  We’re just now starting to get a taste of that, and personally I don’t like it at all.  Think of this as my “sticking it to the Man who hasn’t quite gotten a grip on us but is getting close” year.  This is my Waterloo or something.  Or whatever.

I just realized that the Hoedown isn’t what I wanted it to be.  We were going in the wrong direction.  Don’t get me wrong: it was great.  I think it was even better than last year in the important respects: discussions, networking, presentation quality, attendee satisfaction, etc.  But I want to improve in other areas, too.  And I want anyone who wants to be there to be there.

Like I said earlier, I let a ton of people in for free this year.  Something like 20-30 people out of 100 (and that’s not counting vendors).  This caused huge financial strain (as in, I’ll be shelling out thousands of dollars out of pocket strain), but I realized that having an event people can come and enjoy is more important than putting that $200 barrier in their way.  When I first released my book, people criticized me a lot, saying, “Money is the way of the world and that’s just how it works.  Dropping $40 on a book to learn Ruby and Rails is just how it has to be.”  

I called B.S. and now 100,000+ downloads later, I realized that I’m right.  

A ton of people have enjoyed the language that we all know and love because I decided to say screw the system and toss it out there for free.  Hopefully 100,000 people won’t show up to the Hoedown next year, but I hope that people can come and enjoy the same conferences and community that we’ve enjoyed, just without the price tag attached.

the ruby hoedown…in 10 minutes

Uncategorized — jeremy @ 9:40 am

If you couldn’t make it down to the Ruby Hoedown this past weekend and just can’t wait until ConFreaks get their videos up on the site, then check out the Rails Envy guys’ condensed version over here.

If you’re wondering, the Bocce Ball was the final event in the Showdown at the Hoedown, which yielded Michael Ivey some sweet, sweet Pragmatic Studio love.

the rubyist hath arrived

Uncategorized — jeremy @ 5:09 pm

Just got the 50 copies I ordered for the Hoedown…which ended 2 days ago.  Blast!

If you’re an office and want 5-10 to toss around or a blogger that wants a review copy or something, let me know.  I’ve got plenty to toss your way.

I’m very satisfied with the quality; the only thing that strikes me is that the body text’s font is a little large.  Does anyone else think that?  Or do I just read text at 10pt too often?

write pretty words

Uncategorized — jeremy @ 1:23 pm

So, I’m fielding contributions for the second issue of the Rubyist in case you were wondering.  I highly encourage you to propose something if you’re at all inclined to write about it.  It pays well, and we take articles on just about any Ruby-related topic.  Though each issue has a “theme” per se, we really, really like to mix up the content to give readers a very wide-field view of what Ruby is doing in the world.  So even thought we may have an issue themed around web frameworks, we heartily welcome your article on implementing Tangali Vedic maths in Ruby through metaprogramming.

If you’re interested, drop an e-mail to write@therubyist.com with your idea or even suggestions for articles.

hoedown ‘09 and conference vendors

Links, Ruby, Uncategorized — jeremy @ 8:10 pm

So, if you haven’t heard, here’s the skinny on the Ruby Hoedown 2009:

  • We’re moving to Nashville
  • It’s going to probably be at the OpryLand Hotel
  • And, oh yeah, it’s going to be free.  As in, $0.
I already have a lot of forward momentum of it and I plan on spreading the planning and registration across the whole year (I’m guessing that a free conference may cause registration headaches but hopefully not…).  If you want to sponsor the madness, then please e-mail me.  I need to start gathering funds now so I can put a deposit down on the venue ASAP.

On to other things!  Now that Hoedown ‘08 has passed, I thought I’d take a little time to share some wisdom I’ve gained from two years of doing it.  This isn’t meant to be some sort of authoritative series of posts or anything, but I thought I could just share my experiences and thoughts on conferences, especially Ruby ones.  This time I’m sticking to something tame: vendors.  

When I did the Hoedown last year, I started out having no clue where to find the best vendors for anything.  Google is helpful but the top 50 results are all super-SEO’d (possibly scammy) pages that are actually pretty expensive.  Googling for “cheap conference bags” actually got higher prices than simply “conference bags.”  So, as a service to future conference organizers, I thought I’d share where I get my stuff.  Note that I don’t get a kick back from these people or anything, but they’ve treated me well 2 years in a row so they deserve some lip service.

The conference bags have come from 4Imprint both years.  This place is crazy; they sell promotional version of just about anything you can think of.  But I only order my bags from there so I can’t speak about anything else.  Even so: the bags have been phenomenal both years.  Last year I ordered some nice plastic bags with a one color imprint.  They actually cared enough to call and inform that ink bleed would make me lose some artwork detail and to make sure that was OK.  I was stunned that they would even care, since the last place I had something like this printed at actually used the wrong color and refused to issue a refund.  

This year I ordered some eco-friendly shopping/tote bags.  I caught them on sale for something like 40% off, but even so they aren’t THAT much more expensive than their plastic counterparts (and you get a ton more space). 

I think if I had a choice, I’d totally go with the tote bags again.  People seemed to actually use them more than the other bags and they’re usable after the event.  Plus, they don’t resemble trash when they’re in your house.  WIN.

On RubyFringe’s recommendation, I ordered the conference badges from BandPasses.Com.  These badges are AWESOME.  Flawless printing, good size, and they provide alligator clips. (Photo from Obie Fernandez’s Flickr)


I ordered 200 for $149 with printing on one side.  The product was MUCH nicer than last year’s laser printer mashups (which weren’t terrible but certainly not what I’d call “quality”).  To get the names on the badge I used a simple Avery label with a clear background.

Simple process, especially since the event software I use exports attendee data to CSV which I can import into Word and mail merge into the labels in one step.  DOUBLE WIN.

I always order my custom shirts (Hoedown or otherwise) from CustomInk.  The results have been fantastic every time and always incredibly quick to arrive.  

Both years I’ve gone with one color and the printing has been amazing, but the main concern I find when ordering these sorts of things is the shirt under the printing.  I had to go with a cheaper brand this year than American Apparel (they are about $400 more for AA when ordering about 150 shirts), but if you can afford it I heartily recommend the AA shirts.  They last much longer, don’t shrink in the wash, and by-golly they’re just a heck of a lot softer and comfortable.  

Finally, the event software I’ve used and have been very, very satisfied with is EventWax.

What’s not to like?  It’s written in Rails (I think), it works great for taking money via PayPal/credit card, I can export attendee data to XML or CSV really easily, and I can create new ticket types and discount codes quickly.  Others I know use EventBrite or some such and I’m sure they’re great.  But EventWax works great for me, so I’d encourage you to check it out.

Of course, I also want to plug the ConFreaks guys for handling our recording again this year.  They always do an awesome job and I’m looking forward to see them produce this year’s videos.

Alright…that’s it.  Other than that things were haphazardly acquired (though I can recommend DPSBanners for printing things like window clings and banners!  Ordered at 1p.m. Monday, received 9a.m. Tuesday…crazy) or not acquired at all.  If you have any vendors that you use for things or prefer, please drop a comment or e-mail.  I’m, of course, always looking for better vendors.

the rubyist, a magazine for rubyists

Ruby — jeremy @ 12:12 am

Just wanted to quickly post about something I’ve been working on for a while that has finally reached fruition.  The Rubyist is a technical magazine focused on Ruby that’s available in print and PDF, and I just pushed the first issue to production.  The issue has articles from Giles Bowkett, Ben Scofield, myself, Evan Light, Rein Henrichs, and more.

Check it out (and purchase a copy) here: http://therubyist.com

surveys abound

Links, Ruby — jeremy @ 7:10 pm

Took two really interesting surveys today.  The first is A List Apart’s Survey for People Who Build Websites.  It’ll be interesting to see how the data from last year has shifted this year.  I’m actually really curious to see how the web industry is doing in my area; I know a few people who are in it but not many.

I also took Hampton Catlin’s Survey for People Who Like Ruby (a.k.a., Hampton Catlin’s Ruby survey 2008).  This data should be interesting, especially the question about which interpreter is in use.  I’m very curious about how much traction alternative implementations have gained.

I have more interesting blog entries coming but getting the first issue of The Rubyist out the door (more info on that very soon) and getting The Ruby Hoedown setup (also, more information on that and some reflections coming soon) have eaten up all my time!

 

the ruby hoedown

Uncategorized — jeremy @ 10:21 pm

Only two weeks left to register.  Make sure you get your ticket today!   We’ve got talks from Jim Weirich, Joe O’Brien, Rein Henrichs, Giles Bowkett, David Black, Chris Wanstrath, Rick Bradley, and more!  Check out http://www.rubyhoedown.com/ for more information and a registration link.

reboot: fixing core ruby tools

Uncategorized — jeremy @ 7:38 am

Just for fun and out of pure curiosity, I recently took a jaunt through the code of Rake, RDoc, and friends and I have to say: WOW.  There be demons in there.  If you haven’t taken a look, let me invite you to just take a quick tour.  I’ll wait.

Scared yet?  Of course, no one can really fault any of the authors of these libraries.  Most of them were written eons ago in Interwebs Time™ and certainly before what one would consider “modern” Ruby practices existed.  But as I read this code, I started thinking that there comes a time when a language has to transition to a newer, better toolkit.  We’re going through this with the Ruby interpreter itself as we transition MRI to YARV and from a single implementation ecosystem to a thriving ecosystem with multiple compatible implementations.  Other languages have dealt with similar transitions (have you read the original K&R book?  I have.  It gives me nightmares.  I’m pretty sure that will be my kid’s punishment when s/he doesn’t do their homework), and I think it’s now time for we Ruby folks to revisit the tools we know and love in order to evaluate if perhaps there’s a better alternative.

Dueling documentation tools

Ooh, RDoc.  What to say about RDoc?  I’ve dug around in the internals of RDoc more than anyone ever should.  It’s not really so much RDoc itself that scares me (though the template stuff is uh…interesting), but the CodeObjects stuff that parses and lexes and generally finagles around with the Ruby code.  The structure it produces is vomit inducing.  For example:

[#<RDoc::TopLevel:0x2355154 @includes=[], @done_documenting=false,
@file_relative_name=”README”, @modules={}, @requires=[],
@current_section=#<RDoc::Context::Section:0×23550b4 @title=nil, @file=”",
@sequence=”SEC00001″, @line=”">, @diagram=nil, @attributes=[],
@force_documentation=false, @name=”TopLevel”, @document_self=true,
@visibility=:public, @comment=”== Welcome to docbox!

This is a sample docbox app. Feel free to run around and edit things. Then check
out http://github.com/iownbey/docbox-sample-app/tree/master to see your edits on
the repo. Everything is pushed automatically.

“, @file_stat=#<File::Stat dev=0xe000002, ino=1838991, mode=0100644, nlink=1,
uid=501, gid=20, rdev=0×0, size=233, blksize=4096, blocks=8, atime=Wed Jul 23
23:53:33 -0500 2008, mtime=Wed Jul 23 10:58:25 -0500 2008, ctime=Wed Jul 23
10:58:25 -0500 2008>, @classes={}, @aliases=[], @constants=[], @in_files=[],
@file_absolute_name=”README”, @method_list=[], @document_children=true,
@sections=[#<RDoc::Context::Section:0x23550b4 @title=nil, @file="",
@sequence="SEC00001", @line="">], @parent=nil>, #<RDoc::TopLevel:0×2354b3c
@includes=[], @done_documenting=false, @file_relative_name=”main.rb”,
@modules={}, @requires=[], @current_section=#<RDoc::Context::Section:0×2354a9c
@title=nil, @file=”", @sequence=”SEC00002″, @line=”">, @diagram=nil,
@attributes=[], @force_documentation=false, @name=”TopLevel”,
@document_self=true, @visibility=:public, @comment=”#
#
# This is a very good file.
“, @file_stat=#<File::Stat dev=0xe000002, ino=1364924, mode=0100644, nlink=1,
uid=501, gid=20, rdev=0×0, size=519, blksize=4096, blocks=8, atime=Wed Jul 23
23:53:33 -0500 2008, mtime=Wed Jul 23 10:58:09 -0500 2008, ctime=Wed Jul 23
10:58:09 -0500 2008>, @classes={”FirstClass”=>#<RDoc::NormalClass:0×233aebc
@includes=[], @done_documenting=false, @modules={}, @requires=[],
@current_section=#<RDoc::Context::Section:0×233ae30 @title=nil, @file=”",
@sequence=”SEC00003″, @line=”">, @file=”main.rb”, @superclass=”Object”,
@attributes=[], @force_documentation=false, @diagram=nil, @document_self=true,
@name=”FirstClass”, @visibility=:public, @comment=”#
#
# This is a very good…

That’s a small part of the structure from the very, very simple sample code in docbox.  It’s not only infuriating because it’s completely innavigable, but it also has a huge amount of duplication inside of its structure (it doesn’t use object references or tags to identify tokens, so tokens that have children show up twice as seemingly totally different objects).  

Fortunately, Mr. Loren Segal has been working on a tool similar to something I started building some time ago.  The tool, YARD, creates a very, very nice API on top of all this RDoc garbage.  For example, the above nastiness is turned into something like this:

obj = Registry.at("MyClass")
obj.superclass  # => "Object"

obj = Registry.at("MyClass::some_method")
obj.visibility  # => :public
obj.docstring   # => "This is a great method"

As someone who has written tools to work with RDoc’s structure, this is music…er…to my eyes.  Or something.  Either way, it looks awesome.

The only problem I’m having is that I can’t follow YARD’s development very well.  There is very little public discourse going on that I can find and development is very sporradic.  Won’t someone think of the children and push this project forward!?  I surely plan to when I get time.

God of Thunder or best build system?

I don’t think I’m the only one who gets frustrated with Rake.  While it’s a very convenient way to write build files and automate tasks, it does have its pain points.  It’s pretty OK for a Makefile replacement (which is what it was made for) but sucks for scripting (which is not what it was made for but what people use it for). On top of that, it’s not easily hackable or scriptable (try deleting or replacing a task, something I believe is easier now but was a huuuuge hassle before) due its fairly obtuse architecture and foreign internals.  

But Yehuda Katz has been hacking on a new approach to the build system problem.  Named Thor, it has a few fundamental differences from Rake:

  • It’s not a “just” a DSL.  This is great and sort of bad.  Sort of bad because you lose the nice little DSL look.  BUT, Since it’s just PORCs (plain ol’ Ruby classes), you can create base classes that you can inherit from or test them just like the rest of your Ruby code (THANK YOU!).
  • It’s geared toward scripting.  Which means it has excellent support for command line options and such, unlike the nastiness from Rake (ew…ENV…really?).
  • It has a system wide repository of tasks, a la sake.  You can install remote tasks or tasks from a file into your system wide task set.  Really useful if you end up using the same task on a lot of projects or want to use Thor for more than just a development-related script runner and as more of a shell extension.
  • It’s self hosting.  The Thor runner is simply a Thor class.

While I’m not totally sold on the approach (for example, it’s a lot of extra typing and I think you lose the benefit of a DSL when you put all that Ruby chrome around it, but at the same time, is a DSL even the best approach?), I think it’s certainly an interesting project and something to watch.

Converting from Rake to Thor files is pretty simple.  First, rename the file to Thorfile rather than Rakefile. Next, you’ll need to do a few little tweaks here and there to make it work.  For example, if we had a Rakefile like the following:

# Run this like rake db:encoding DATABASE=thing BANNER=true
namespace db
  desc "inspect a database's encoding"
  task :encoding
    encoding = Database.get(ENV['DATABASE']).encoding
    puts “Your app - 1.0″ if ENV['BANNER']
    puts “Database’s encoding is #{encoding}”
  end
end

You’d change it to a Thorfile like so:

# Run like thor db:encoding thing banner=true
class Db < Thor
  desc "inspect a database's encoding"
  method_options :banner => :boolean
  def describe(database, opts)
    encoding = Database.get(database).encoding

    puts "Your app - 1.0" if opts[:banner]
    puts “Database’s encoding is #{encoding}”
  end
end

Since I do a lot of scripting in Rake, this command line options stuff looks amazing.  I wouldn’t have to have so many config files floating around inside of my code if I had this! :)

I’d love to see Thor replace Rake, simply due to the cleanliness of code, but I’m worried about compatibility.  Something like my API compatible Rake replacement named Lake (which I recently lost in a hard drive crash.  Blast!) would be the optimal, but I think if Thor adds more compelling features and a Rake compatibility layer, it will the top dog for Ruby build systems.

Putting Test::Unit to the test

While at Railsconf this year, I asked Nathaniel Talbott (the original author of Test::Unit) what he thought about Ryan Davis’s plan to replace Test::Unit with his miniunit in Ruby’s standard library.  He said he thought it was a great idea, especially since he thought a lot of the code in Test::Unit was stuff to be embarrassed of.  We then had a long discussion about how we should set a moratorium on code responsibility for things we wrote over a year ago… ;)

This one isn’t as exciting as the other tools.  It’s the exact same API, the same functionality (with a few extra features and a few minor features removed), but the code base size difference is crazy.  As in (code stats taken from a post on ruby-core):

miniunit
——–
 lib  loc     646 total
 test loc     905 total
 totl loc    1551 total
 flog = 711.105369946191

test/unit
———
 lib  loc    3571 total
 test loc    2464 total
 totl loc    6035 total
 flog = 3103.27739878118

A testing lib that’ 1/4 the size, better tested, has more hackable code and the same features?  Yeah, I’m there.  There’s currently a debate on ruby-core as to whether this should actually replace Test::Unit or not, but I think eventually we’ll see it in core (at least, I and the author of Test::Unit really hope so…).  The argument seems pretty weak to me (basically, it’s different and we’re not sure about it), but one could say that about nearly every feature in 1.9.

So, that’s my list of tools that will pwn the tools we use now.  Do you have any to add to the list or change? I’m always interested in alternative approaches to things.

Next Page »
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2008 omg blog!! lol!! | powered by WordPress with Barecity