Posted by kev
Tue, 19 Dec 2006 09:24:00 GMT
Update: Ruby2Ruby is having gem propogation issues. Feel free to download the gem here directly and install via gem install ruby2ruby-1.1.2.gem.
Update 2: We’ve found a bug in the loading that causes problems when you supply a method to Heckle. A bug fix has been checked into the repo and we’re preparing a release. Look for 1.1.1 soonish.
Update 3: Ok, 1.1.1 is out the door. The gem server is syncing, so look for a new version this afternoon (12/20) with several bugs including the loading error fixed.
Yes, I know what you’re thinking. “Holy crap, Kevin posted for the first time in months! I thought he died, or got eaten by a corporate zombie, or set out on a epic adventure to find himself.” But hey, good things come to those who wait, right?
So, you’ve been waiting, and I’ve been writing Heckle. It’s a good thing.
Heckle is a mutation tester. It modifies your code and runs your tests to make sure they fail. The idea is that if code can be changed and your tests don’t notice, either that code isn’t being covered or it doesn’t do anything.
It’s a little weird, I know, but I like to think about it as pen-testing. It’s like hiring a white-hat hacker to try to break into your server and making sure you detect it. You learn the most by trying to break things and watching the outcome.
Anyway, Heckle was inspired by Jester, and Ryan Davis wrote a proof of concept at RubyConf. As he notes, I went a little nuts and much of the current implementation I rewrote that night or on the plane home.
You can install Heckle from Ruby Gems:
gem install heckle --include-dependencies
Let’s take the new toy out for a test drive.
Read more...
Posted in Hacks, testing | 10 comments
Posted by kev
Sat, 16 Sep 2006 01:54:00 GMT
Today I checked in version 0.5 of ARTS into my plugin repository. This release adds support for page['some_id'].toggle and friends.
In general the assertion looks like:
assert_rjs :page, ELEMENT_ID, *METHOD_CALLS
So, to match page['some_id'].toggle you use:
assert_rjs :page, 'some_id', :toggle
You can continue to string as many method calls as you’d like. To match page['some_id'].toggle.up.down.left.right.everywhere:
assert_rjs :page, 'some_id', :toggle, :up, :down, :left, :right, :everywhere
Finally, for assignment make sure to append an ‘=’ to the method name and include the value. For example, to match page['some_id'].style.color = 'red':
assert_rjs :page, 'some_id', :style, :color=, 'red'
Go check it out.
Posted in Rails, testing | 3 comments
Posted by kev
Mon, 11 Sep 2006 00:55:00 GMT
Hi guys. One of the reasons ARTS still doesn’t have support for the square bracket syntax of RJS is that I haven’t thought of a form of assertion I’d like. I think this might work:
assert_rjs :page, 'foo_id', :toggle
:page is used to denote the [] syntax and foo_id is the id of the element we’re working with. All subsequent chained methods follow afterwards as symbols like :toggle.
This example would match page['foo_id'].toggle.
What do you think? Do you have a better idea? Please do give me your thoughts. This is the one major hole in ARTS and I’d like to get it patched up.
Posted in Rails, testing | 1 comment
Posted by kev
Mon, 04 Sep 2006 22:16:00 GMT
Rabble just released an article on his Testing Rails Blog on how to run tests on deploy with Capistrano. It covers basic Capistrano tasks that will work with a single deployment server and then goes into some more advanced tasks for multiple server deployment and concurrent deploys. Go check it out.
Posted in Rails, testing, sightings
Posted by kev
Sun, 03 Sep 2006 21:23:00 GMT
In case you missed the changeset, Assaf Arkin’s assert_select has been included in EdgeRails. This officially marks the deprecation of assert_tag.
I think this is a good thing. I always found the syntax of assert_tag ugly. assert_select looks to be a fine replacement.
If you aren’t running edge, it is available as a plugin.
Posted in Rails, testing
Posted by kev
Sat, 02 Sep 2006 23:30:00 GMT
Today I decided to see how much of the test code in my current side project I could rip fixtures out of. At the same time I could see what kind of speed increase I got from staying away from the database. Model tests seem to be the most straight forward so I started there.
Read more...
Posted in Rails, Ruby, testing | 2 comments
Posted by kev
Fri, 01 Sep 2006 18:18:00 GMT
This post just blew me away. Turns out instead of using the delegate_method_to_mock! method I posted the other day, I could use Mocha and just save myself the time. Check this out:
Using Flexmock (and my custom method):
def test_process_exit
delegate_methods_to_mock!(RailsFCGIHandler, :close_connection) do
fcgi = flexmock()
fcgi.should_receive(:close_connection)
@handler.mock = fcgi
@handler.stubs(:when_ready).returns(:exit)
@handler.process!
end
end
It works but it’s none too pretty. Flexmock people, if there’s a better way speak up.
Here’s the equivalent using Mocha:
def test_process_exit
@handler.expects(:close_connection)
@handler.stubs(:when_ready).returns(:exit)
@handler.process!
end
I can place expectations directly on my object (even though I didn’t create it as a mock) and it takes care of it for me. That is *so* much clearer and I’ve saved 3 lines that didn’t tell me anything new about my test. I think I’m in love.
Posted in Ruby, testing, sightings | 3 comments
Posted by kev
Wed, 30 Aug 2006 21:15:00 GMT
I’ve been playing a lot with mocks lately (and I’m a bit post happy today) so I thought I’d show off a bit of code that was useful in a patch in RailTies.
Sometimes methods are hard to mock. They aren’t calling actions on some object you can replace with a mock or the API was designed so it’s hard to inject the mock in the first place.
This bit of code lets you intercept a method call and redirect it to a mock object of your choosing:
def delegate_methods_to_mock!(klass, *methods)
methods.each {|m| redefine_method_using_mock! klass, m }
yield
methods.each {|m| reset_method_using_mock! klass, m }
end
def delegate_method_to_mock!(klass, method)
redefine_method_using_mock! klass, method
yield
reset_method_using_mock! klass, method
end
def redefine_method_using_mock!(klass, method)
klass.send(:attr_writer, :mock) unless klass.respond_to? :mock=
klass.send(:alias_method, "nonmocked_#{method.to_s}", method.to_s) unless klass.respond_to? "nonmocked_#{method.to_s}"
klass.send(:define_method, method,
Proc.new {|*args|
@mock.send(method, *args)
}
)
end
def reset_method_using_mock!(klass, method)
klass.send(:remove_method, method)
klass.send(:alias_method, method, "nonmocked_#{method.to_s}")
end
So then we use it like:
def test_process_exit
delegate_methods_to_mock!(RailsFCGIHandler, :close_connection) do
fcgi = flexmock()
fcgi.should_receive(:close_connection)
@handler.mock = fcgi
@handler.stubs(:when_ready).returns(:exit)
@handler.process!
end
end
What happens is that an accessor is placed on the object in question and the method you want the mock to intercept is redirected to call on the mock instead… so it goes like this:
I call someobject.blah(1,2,3) which would normally call someobject.a(1,2,3) (may be a protected method) but instead we redefine a to call @mock.a(1,2,3) so we can register the call.
I’m not entirely sure if this is the best way to handle it but it seems to be working for my needs at the moment.
Posted in Rails, Ruby, testing | 3 comments
Posted by kev
Wed, 30 Aug 2006 19:36:00 GMT
I’m starting to come around on the subject of using mock objects as opposed to just letting the code run. Here’s why:
Loaded suite UnitTests
Started
.....................................................
.....................................................
.....................................................
.....................................................
Finished in 0.070892 seconds.
212 tests, 250 assertions, 0 failures, 0 errors
Loaded suite IntegrationTests
Started
...................
Finished in 0.046002 seconds.
19 tests, 24 assertions, 0 failures, 0 errors
Loaded suite AcceptanceTests
Started
...............
Finished in 0.007645 seconds.
This is from the tests that are bundled with Mocha, a mocking library.
Look at those numbers! Look at just the unit tests. 212 tests, 250 assertions, 0.070892 seconds. Hot damn. Imagine your Rails tests running like that.
Posted in Ruby, testing
Posted by kev
Tue, 22 Aug 2006 17:49:00 GMT
Are your test runs dull and listless? Do you miss the red/green bar of JUnit? Well, now you don’t have to! Between Pat Eyler’s RedGreen and Chris Wanstrath’s modifications you can have red, green and yellow tests. That doesn’t sound nearly as cool written, but take a look:

It makes me happy. Oh, and a 3 line addition to your ~/.autotest will make colorized autotest runs (pictured above).
Posted in Ruby, Hacks, testing