Posts

Employee Appreciation

As a consultant, I spend a lot of time at big companies and big companies generally have a morale problem. Bureaucracy, cubicles, and lax management will tend to do that. Typically they try to solve this problem by exchanging money for goodwill. A few projects ago I was consulting at one such company where they spent a ton of money having a day of games, burgers, and events during business hours. There was a big ad campaign, lots of promotional tie-ins and give-aways -- a team of people clearly worked on this for weeks (or maybe months). Now add up productivity, food, and sumo-suit rental costs and we are talking some serious money. All worth it in service of employee good will, right? A few days after this spectacle, my team and I decided to walk to lunch. Now the most direct route to our restaurant of choice happened to be through the front door. However, the security guy stopped us when we tried to leave. Employees aren't allowed to enter or leave through the front door....

Metrics for Rails

Everyone thinks they write good code -- it's just part of human nature. You can't do something every day and not secretly suspect that you're good at it. Self-delusion is a powerful thing so you need to use metrics to take a hard look at your code. On my current project, we've just added a daily metrics build (run every day at midnight by CruiseControl.rb ) that takes a look at our code in three ways: Code coverage with Rcov Cyclomatic complexity with Saikuro And um..., Flogging with Flog Rcov is a code coverage tool that can be used with Rails Rcov to add a bunch of rake tasks to your build so you can figure out which lines of code are run by your tests... and which are not. Saikuro computes cyclomatic complexity which "measures the number of linearly independent paths through a program's source code." Methods with more paths are harder to understand/debug/modify. And Flog is cyclomatic complexity with an attitude. It scores ruby methods with an ...

Why 50% Test Coverage Seems More Painfull Than No Test Coverage

Recently I was on a project where a bunch of code had been written before we arrived. It was quite a struggle to get the application under test. After a number of months the team hit 50% and then we just stayed there. We had a hard time getting client developer buy-in on the push upward from 50%. I didn't really understand this attitude at first, but after talking with the devs, I realized that the tests were mostly a nuisance for them. They saw it like this: "If I have to gut a few pages, as part of a changing requirement, now I also have to spend a day fixing the stupid tests. And the tests never really catch any bugs, so what was the point? All the tests are doing is slowing me down." Since the coverage was low and many of the test writers were new to unit tests we didn't really have a lot of protection from bugs. But we also had a sizable suite to maintain. They were feeling all the pain of keeping a test suite running but seeing none of the benefits. ...

Renting American Cars

Image
As a traveling consultant I've developed a pretty poor opinion of American cars. Sliding doors that won't close, unfathomable glove boxes, ugly/boring interiors, boring/ugly exteriors, crazy placements for the radio/ac/heating/trunk release buttons, plastic doors with tails of extra material hanging off poorly drilled holes... The other day I was sitting in a Chrysler 300 talking with one of our tech leads about how he really wishes the rental company hadn't upgraded him and would've much preferred a Hyundai Elantra -- a car that costs half as much as the 300. It's a bit depressing.

Writing Your Own Custom Log Parser

I spent the last week writing a log parser of all things. The web site I'm currently working on is the sign-up page for a large company so they are very concerned about how far the average joe gets into the process before they give up. If everybody bails on the address page, then perhaps it's too complicated or unresponsive or... something. Up till now we've been redesigning pages based on some data and a lot of guesswork so we thought it might be about time to get some serious data on every session every day. Now the first thing you learn about parsing rails logs is that they are designed to be human readable but not so much computer parsable. An Apache request is one line. A Rails request log has lots more info, but is multi-line. And since we run a lot of Mongrel instances at once, all these requests are interleaved, so sorting them out is an intense computation (we actually ran out of memory a few times before we did some optimization). Our first pass was mostly ...

RSpec on Rails: Models

In my last post I talked about using RSpec without Rails, but since just about all my Ruby programming involves Rails, I should probably get into how to specify Rails code. RSpec on Rails: Models So if you're new to RSpec and you want to get started quickly, head on over to rspec.rubyforge.org , get RSpec, Spec::Rails and then, after you've created a new Rails project and rspec-ed it (all detailed on the website) you can run: ruby script/generate rspec_scaffold person name:string phone_number:integer cash:decimal Which will get you a bunch of stuff to play with. Of you'll need to set up your database.yml and run rake db:migrate if you want thing to work. Fire up your favorite IDE and find the person_spec.rb and you should see something like: require File.dirname(__FILE__) + '/../spec_helper' describe Person do before(:each) do @person = Person.new end it "should be valid" do @person.should be_valid end end Not the world's mos...

RSpec without Rails

I'm going to try and turn my recent presentation on RSpec into a series of blog posts -- This being the first. Before I get on with it I would like to thank the Houston Ruby and Rails Users Group for having me. They asked some pretty insightful questions and were generally a great audience. I'd also like to thank ThoughtWorks for paying for my flight, rental car, and lost billable hours so I could do this presentation. RSpec without Rails So in order to show you how RSpec works, I'm going to start with specifying a class that deals with string case like so: require File.dirname(__FILE__) + '/../spec_helper' require 'string_caser' describe StringCaser do it "should upcase a string" do caser = StringCaser.new("A String") caser.upcase.should == "A STRING" end end After requiring a spec_helper and the file I intend to spec, I set up a 'describe' block. Inside the block there is a single spec (or example) which is als...