Posted about 1 year back at Not So Stupid
In case you have been sleeping in the same cave as Osama Bin Laden, Apple's new OS X Leopard includes Ruby as a first-class language.
But Apple's effort to make the language and all it's extensions universal binaries can cause you some trouble when installing gems that require compilation.
If you're installing ...
Posted about 1 year back at Not So Stupid
One of the parts of rails that some people consider "ugly" and go to greath lenghts to "clean up" is the use of numeric ids in URLs: /accounts/edit/12.
URLs are considered extremely valuable real estate. Not only because users have to see them all the time, but also because search engines ...
Posted about 1 year back at Not So Stupid
Here's a little hack for those of you that run Rails' script/server on its own window or tab.
By inserting a couple of lines into the server script, you can have it change the title of the window or tab it's running on, making it a lot easier to look for ...
Posted about 1 year back at Not So Stupid
If you did not attend RubyConf 2006, then please see this movie first.
If you did attend the conference, or you have seen "Erlang, The Movie" before, then this needs no other explanation:
Erlang, The Ringtone.mp3
Posted about 1 year back at Not So Stupid
Joel is wrong when he says that you should pick a safe language (Java, C#, PHP or maybe python) if "someone is going to get fired".
He almost got it right: You should go with a safe language if you're afraid of being fired for picking the wrong language.
And in fact, ...
Posted about 1 year back at Not So Stupid
This is an extraction of some things we've been using at StreetEasy for about two years now. Here's the README:
Just like the traditional render :partial, embedded actions allow you to
refactor your views and extract presentation logic and templates into separate
files.
Unlike partials, embedded actions also let you define business logic to ...
Posted about 1 year back at Not So Stupid
Thought #1: "enterprise software development" is that particular kind of software development where the process matters more than the results.
Thought #2: "enterprise software" it's the same category that includes those billions of lines of COBOL code that used just two digits to store year values.
Posted about 1 year back at Not So Stupid
(I just submitted this story to Slashdot, but I didn't want to see this masterpiece get lost in the bowels of their submission queue, so I'm also posting it here. Update: it got accepted)
The developers of Rubinius, an experimental Ruby interpreter inspired by SmallTalk, have been discussing the possibility of ...
Posted about 1 year back at Not So Stupid
I've been abusing Ruby exception handling lately. Instead of doing something like:
if user and user.group
user.group.do_something
end
or a cleaner
user and user.group and user.group.do_something
I just do
user.group.do_something rescue nil
And let Ruby deal with the consequences of a missing link.
It was all nice and pretty, until I saw this little guy standing in ...
Posted about 1 year back at Mike Clark
Herewith, responses to my survey How Would You Test This? regarding tools and techniques folks are using to test Rails controllers, and my humble thoughts at the end.
Mike Mangino shows you how he'd write an RSpec spec for my controller, and points out the style they use on projects.
"Our goal with controller tests is to create very simple, easy to read tests that cover the entire controller. We believe strongly in one assertion per test, so we will have a larger number of small tests. Our typical pattern is to stub everything at the beginning, and then mock as necessary to validate behavior."
Pat Maddox has found "testing controllers is generally child's play, and the model is where I run into the most trouble." He offers a step-by-step tutorial for BDDing my controller from start to finish using RSpec, and concludes with
"My controllers are easy to spec because they should be easy to spec. They just take some objects and tell them to do stuff. It's what those objects do that is complex. You can use mock objects to isolate that complexity. If you don't use mock objects, then you end up with leaky abstractions that make your tests harder to understand and maintain."
Jay Fields has never been able to accept that controllers can only be functionally tested. He looks forward to the day when we can instantiate controllers anew and unit test them:
"I think part of the problem is that controllers are not Good Citizens. Controllers violate the first rule of Good Citizenship. Upon creation (Controller.new), controllers are not in a valid state. Instead, controllers depend on being initialized within the framework and having their state set post construction time. That ends up being a problem for unit testing since it requires each test to set additional state on newly created controllers."
James Herdman wrote in to say he's a "hold the onions" sort of guy who prefers real objects over mocks/stubs whenever possible.
"Avoiding the database would be nice, but sometimes it's good to hit up your models in controller testing. Sometimes the angle at which we hit our models in the controller isn't quite as we intended when writing our models, or sometimes you expose bad behavior you didn't quite realize could happen... I play by this rule of thumb when it comes to mocking and stubbing with controllers: Fake out stuff that doesn't really matter, and fake out what's directly out of you control (e.g. external resources). (The drawback is, of course, that my tests take bloody ages to run through. But I'd rather stuff go afoul on my system than in production.)"
Kevin Barnes gave a nod to the shoulda plugin and finds the nested contexts to be handy on his "large-scale Rails app (EMR w/ 120+ models)".
Jim Morris uses RSpec with mocks, and pointed out a technique he came up with to automatically test all actions within a controller using RSpec.
I appreciate the time these folks took to write up examples and opinions. Hearing how other Rails developers are going about testing controllers gave me new perspectives, and that always helps me. I hope you picked up a new idea or two along the way, or maybe even found more confidence in the approach you're using. Indeed, perhaps you realized that you're already doing what the other cool kids are doing. At the same time, I appreciate that seeing varying tools may inadvertently cause some paralysis among those folks trying to get started.
If all this left you wondering how to get started, I offer you this embarrassingly obvious, but painfully honest, experience report: Testing is 90% discipline. The hard part is actually sitting down and doing it on a regular basis, where regular basis means "as you're writing code". Whether it's before or after you write the code, with Test::Unit, RSpec, test/spec, or tomorrow's testing framework, using mocks, stubs, or neither of the above is an implementation detail. Now, the tools and techniques (the other 10%) can help you keep the discipline. So choose tools that you're comfortable using on a regular basis, regardless of what's cool, and stick with them. And then focus the energy you might otherwise be spending on the worry of whether you're doing the right thing on the thing that matters most: Making great software.
Posted about 1 year back at Mike Clark
You know you've been programming too much when you spot this train and the picture title immediately pops into your head.
Posted about 1 year back at Mike Clark
I've spent many a day tuned in to "A Prairie Home Companion" while motoring through Kansas, Wyoming, and Arizona. Indeed, just hearing Garrison Keillor's comforting voice reminds me how thankful I am to pick up an AM station. (Yes, I have an iPod now, but if you've ever driven through the aforementioned states, you'll appreciate the entertainment value of channel surfing the ol' radio and the sheer joy of discovering something intelligible.)
Now I don't know much about Garrison Keillor. To me he's just a disembodied voice that helps the miles melt away. To fellow motorists (all two of them) he's what causes them to wonder why the idiot they just passed is chuckling to himself. But this weekend our local newspaper ran an electronic interview
with Garrison, and two responses struck a chord with me.
On writing:
“Writing is revising. You just keep messing around, cutting the dead
wood, forcing the plants to bloom, until whomever you're writing the piece for
gets exasperated and then you send it to them.”
On performing on stage:
“Near-sightedness is the secret. The audience is just a big warm blur,
very Renoiresque, like a hillside of flowers, and I don't see them as
intelligent, critical individuals. I see them as flora. When I talk on stage,
I'm talking to a few friends who I imagine are listening to the show (actually
they don't, most of them are too busy, some of them have been dead for years).
It's the power of illusion. If I actually saw the danger I am in, I would run
in terror.”
Posted about 1 year back at Mike Clark
Every Halloween after all the kids have sufficiently ransacked the neighborhood,
the porch lights go dark and everyone meets up for the traditional chili cookoff.
It tends to dissipate the effects of the sugar rush, and it's a welcomed relief
from the cold. Plus it's a great way to catch up on the neighborhood gossip,
so they tell me. I go to taste all the chilis.
This year they had an official chili guide printed. The recipes aren't
recorded anywhere that I know of, but the guide was there to warn your
taste buds. I snagged a copy of the guide because I liked the names and creativity.
#1: Killer Chili
* The one that started this madness...
* Contains bacon, beef, and pickled cactus
#2: Merrle's Chicken Tortilla Soup
* Served for 2-3 Halloweens
#3: Bean Chili
* A repeat favorite for the past 3 years
* Contains kidney, black, and pork & beans
#4: Traditional Green Chili
* New this year!
#5: Mescalero Chili
* New this year!
* Contains ham, roast, sausage
* Has NO chili powder or cumin
#6: Bad Attitude Chili (Texas style)
* New this year!
* Contains beer, bourbon, and baker's chocolate
* Also has smoked paprika (weird, we know...)
They were all outstanding. The Traditional Green Chili was my fav this year,
with Bad Attitude Chili coming in a close second.
Posted about 1 year back at Mike Clark
The Rails community raised over $33,000 in charitable donations during this year's RailsConf. Your conference could make a big impact, too!
If you're planning to run or attend a conference, please consider making it a fund-raising event. It's easy to do, and the payback can make a significant difference in the lives of people around the world. I'm more than happy to answer any questions anyone might have about how fund raising was organized during RailsConf.
A great big THANK YOU to everyone who participated!
Posted about 1 year back at Mike Clark
It's not a trick question, and there is no right or wrong answer. The state of
the art of Rails testing has evolved since the early days. Keeping up has
proven both rewarding and at the same time a bit of a struggle. I'm
continually refining the way I write tests to help break writing the code down
into small, safe steps and defer decisions with confidence. And I'm generally
curious to see how you're testing controllers these days.
Why controllers? Simply because they feel more challenging to test than
models. And folks who are perfectly fine with test-driven development at the
model level are often overcome with reluctance and frustration when they start
coding controllers. The hesitation has an upside: It prompts one to move
business logic into models, where the logic belongs and where it's easy to
test.
However, the frustration has a downside. Having fattened up the models, it's
easy to then throw in the towel when it comes to testing controllers. But
given that we're writing web applications—and controllers are central to
how the world accesses our models—it seems fairly important to test
controllers. That means being able to easily flesh out what can happen at a
specific place: Given a particular state, if you poke a controller action in a
particular way, what happens to the state (model objects, the session, visible
display, etc.)?
Assume, for example, that you have the following simple create action in a controller, or assume you want to use TDD to force the writing of a similar create action:
class MenuItemsController < ApplicationController
def create
@menu_item = MenuItem.new(params[:menu_item])
if @menu_item.save
flash[:notice] = 'MenuItem was successfully created.'
redirect_to menu_items_url
else
render :action => :new
end
end
def new
@menu_item = MenuItem.new
end
end
Nothing exciting going on here. It's basically the same create
action you've been writing since Rails 0.10.0. (I've removed the use of
respond_to in this example just to keep it as simple as possible.)
Testing this action isn't especially difficult, but as an example it allows us to focus
on style. And in this brave new REST world where most controllers will have a
create action similar to the one above, style matters. If the
mechanics of writing a test get in the way of describing behavior we aim to
implement, they'll we'll hate writing tests in exactly the way programmers are
supposed to hate testing.
So, how would you go about validating the behavior of the create
action? I'm hoping that by soliciting solutions we can all learn something. To
help get things started, I offer the following styles that I've observed
across a number of projects.
The Classic Cheeseburger
Your basic, get 'er done functional test topped with an
assert_difference custom assertion (the cheese) that checks
whether a new menu item was created in the database.
class MenuItemsControllerTest < Test::Unit::TestCase
def setup
@controller = MenuItemsController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_create_with_valid_menu_item
assert_difference(MenuItem, :count, 1) do
post :create, :menu_item => {:name => 'Classic',
:price => 4.99}
end
assert_not_nil assigns(:menu_item)
assert_not_nil flash[:notice]
assert_redirected_to menu_items_url
end
def test_create_with_invalid_menu_item
assert_difference(MenuItem, :count, 0) do
post :create, :menu_item => { }
end
assert_not_nil assigns(:menu_item)
assert_nil flash[:notice]
assert_response :success
assert_template 'new'
end
end
Hold The Onions
This is the classic cheeseburger, marinated with FlexMock to remove the
bitter aftertaste of the database. Tastes best with a healthy side dish of
unit tests that check model validations, so the functional test doesn't have
to.
require 'flexmock/test_unit'
class MenuItemsControllerTest < Test::Unit::TestCase
def setup
@controller = MenuItemsController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@attributes = { 'name' => 'No Onions', 'price' => 4.99 }
@menu_item = flexmock(MenuItem.new(@attributes))
flexmock(MenuItem).should_receive(:new).with(@attributes).once.
and_return(@menu_item)
end
def test_create_with_valid_menu_item
@menu_item.should_receive(:save).with().once.and_return(true)
post :create, :menu_item => @attributes
assert_equal @menu_item, assigns(:menu_item)
assert_not_nil flash[:notice]
assert_redirected_to menu_items_url
end
def test_create_with_invalid_menu_item
@menu_item.should_receive(:save).with().once.and_return(false)
post :create, :menu_item => @attributes
assert_equal @menu_item, assigns(:menu_item)
assert_nil flash[:notice]
assert_response :success
assert_template 'new'
end
end
The Daily Spec-ial
A light, sugary topping of test/spec on an old favorite, with a distinct flavor of BDD.
require 'test/spec'
require 'test/spec/rails'
require 'flexmock/test_unit'
context 'Creating a new menu item' do
use_controller MenuItemsController
setup do
@attributes = { 'name' => 'Daily Special', 'price' => 4.99 }
@menu_item = flexmock(MenuItem.new(@attributes))
flexmock(MenuItem).should_receive(:new).with(@attributes).once.
and_return(@menu_item)
end
specify 'should redirect to index with a notice on successful save' do
@menu_item.should_receive(:save).with().once.and_return(true)
post :create, :menu_item => @attributes
assigns(:menu_item).should.equal @menu_item
flash[:notice].should.not.be.nil
should.redirect_to menu_items_url
end
specify 'should re-render new template on failed save' do
@menu_item.should_receive(:save).with().once.and_return(false)
post :create, :menu_item => @attributes
assigns(:menu_item).should.equal @menu_item
flash[:notice].should.be.nil
status.should.be :success
template.should.be 'new'
end
end
The Whole Enchilada
This ain't no burger. It's an entirely different kind of (test-lingo-free) taste, smothered in a spicy RSpec syntax and served with a side of refried mocking.
require File.dirname(__FILE__) + '/../spec_helper'
describe MenuItemsController, 'Creating a new menu item' do
before do
@attributes = {'name' => "Enchilada", 'price' => 4.99}
@menu_item = mock_model(MenuItem)
MenuItem.should_receive(:new).with(@attributes).once.
and_return(@menu_item)
end
it 'should redirect to index with a notice on successful save' do
@menu_item.should_receive(:save).with().once.and_return(true)
post :create, :menu_item => @attributes
assigns[:menu_item].should be(@menu_item)
flash[:notice].should_not be(nil)
response.should redirect_to(menu_items_url)
end
it 'should re-render new template on failed save' do
@menu_item.should_receive(:save).with().once.and_return(false)
post :create, :menu_item => @attributes
assigns[:menu_item].should be(@menu_item)
flash[:notice].should be(nil)
response.should be_success
response.should render_template('new')
end
end
This menu of controller testing styles is far from comprehensive, and it's not
intended to be a subjective comparison. I specifically tried to introduce
subtle variations along the way, while preserving the initial goal of testing
the create action. Each style has its pros and cons. Perhaps just
seeing a few different styles will trigger new ideas.
Now it's your turn to blog up a solution. Which tools and techniques are working for you? Send me links and I'll write a follow-up post summarizing the results. As well, I'm looking forward to seeing how Jim and Joe solve this in their Test-Driven Development with Rails Studio next month. I'd enjoy the opportunity to chat with you there.
1 ... 467 468 469 470 471 ... 634