I recently came across a test where I would have had to duplicate a ton of code. Not very “ruby,” IMHO.
So, use MetaProgramming to write the tests for us!
Of course!
For this specific instance, I had to write a bunch of tests that tested how emails were handled in an application (a soon-to-be-publicly-available-mms-receiver drop-in plugin at that).
So, rather than writing tests over and over that look the exact same.
Meta-tize
Ruby gives you a way to define methods on the fly using define_method. Very clever.
So, let’s stop the talk and start the fun!
In my test, I have the following (stripped for space)
%w(email1.mail email2.mail).each do |method|
define_method("test_receive_email_named_#{method}".to_sym) {
# TEST GO HERE
}.to_proc
One thing you’ll notice is that your output needs to be the exact same across the tests. So, this is only helpful if you are testing the rigidity of a model against different data to achieve the same result (that sounds a lot like a lot of tests I write…).
Second thing is that the define_method expects the name of the method to be a symbol and the block to be a proc. You don’t want to define a block in a define method that will execute immediately, of course. You want it to be called when the method is defined. So, we have to convert it into a proc in the define method, rather than leave it as a block.
That’s pretty much it! How cool, ey?
Thanks Matz!
The green bar
There is something very satisfying about seeing the green bar. If you are not sure what I am talking about, check out TDD, Textmate, and most importantly ZenTest (okay, this is also a big help).
So who the heck cares about Test Driven Development?
You know you heard it from your Java teacher and hated using it in JUnit. But, there is hope and rationale for using it.
Okay, yeah, this is another post about testing, but it’s super important and super cool. I plan on updating this post in the future and possibly turning it into a page, but I’m going to list out my practices in testing and hopefully it’ll help someone else. I’ll also explain some schtuff and we’ll work it out together, w00t.
Okay, here goes:
When/what to test
Test your own code. We all know that the rails framework is well-tested, so why test their code?
I write tests on all my models that require my model to behave like I want it too. I am guilty of doing something like this though:
def test_title_should_have_limit_on_title
post = Post.new
post.title = "title is no longer than it should be"
assert post.save
end
(Okay, so that is a contrived example). But, what exactly is that testing? It’s testing the rails framework! We don’t need that. The test could be written to test the constraints of the application. For this instance, I’d write it closer to the actual application specs to ensure that it didn’t break.
Functional test
Holy crap, I hate functional tests, but they are so useful. God, someone get me a napkin, some yogurt just splurted out my nose, that’s how angry I am about my love/hate relationship with the buggers! The functional test can show you exactly what you are doing with a controller and when. For instance, when I have a complicated controller situation, rather than press buttons in the browser, I just watch my little red bars and enjoy the sight of all the work I have to finish.
For instance, I have several places where I use abstract controllers in my applications. Those are perfect to test! What happens if a user is logged in and goes to a place where they have to be logged out, or visa versa?
Write a test!
def test_register_a_user
get :register
assert_response :success
post :register, :user => {:email => "ted@teddy.com", :password => "testy", :password_confirmation => "test", :username => "teddy"}
assert_response :success
end
How wonderful!
Now, I really should be getting back to work. I’ll shuffle off the work-papers soon and write some more of this post, but… for the time being, enjoy the shortness. You can read it on your iPod, probably and not even have to scroll down. Well, maybe once.