Tuesday 18 December 2007

Rails gotchas: All the fixtures in the world

After having spent three hours debugging an error that "couldn't be happening" I have decided to just start loading every fixture for every functional test... Ok maybe not - but that's what it feels like is necessary.

The test in question was there to check if a user with expired quota could start using a feature again once they'd been given more quota. It was failing because I hadn't included the "roles" fixture... vital to the controller when deciding if the user is authorised to get into the controller in the first place... but not really directly relevant to this test, so I hadn't thought about it.

This can also cause the weird effect where an entire functional test suite runs fine when you call it via ruby test/functionals/<whatever>.rb, but several tests fail when you try to run it via rake test:functionals

Lesson: include every fixture that might be accessed by your controller in the performance of its duty - even if it doesn't seem directly relevant.

Friday 14 December 2007

The Economics of IT salaries

I have been reading a book called "The undercover economist"[1], which mentioned the problems with "asymmetric information" in negotiations. It's discussed on pp112-115, if you want to look, but to summarise, the problem is thus: A 2nd-hand car salesman is trying to sell all their cars - whether they are peaches or lemons, and wants to get the best price for each. The buyer is not willing to pay as much for a peach as for a lemon. The salesman knows if any given car is a peach or a lemon, but the car buyer does not. This is the "asymmetric information".

The salesman will, of course, say "all my cars are peaches" (especially if they are not) and to try to charge accordingly. The buyer must then decide if it worth the risk of potentially paying peach-prices for a lemon. If there is no accurate way of telling one car from another, they will often choose not to buy at all.

The problem is that even if the car really *is* a peach - the customer will still not be able to believe the salesman... after all, he'd say that if it was a lemon too.

In this case, both the salesman and the customer lose out, because the salesman is in command of information that the customer is not (ie the "peachness" of the car in question).

The only way out of it is for the salesman to offer undeniable proof of a car's "peachness". The customer can then trust that the car is worth the price - and is more willing to buy.

In Australia, this is done with independant inspections, (eg done by the NRMA). A customer can be fairly certain that a car that has passed inspection meets a basic level of quality. Doing these tests takes more time that the average car-buyer has (especially when they have so many to look over), but it's worth the time for the salesman to get it done, as they then have undeniable proof of peachiness.

But it's relatively easy to verify the quality of car: does it, or does it not have working brakes? Well, test the brakes and see if they work!

What if it weren't so easy - with a set of skills that are subjective, and tests that are at best indirect, and at worst misleading. For example, how do we tell if one IT-worker is more skilled than another? How do you measure skill in IT? and who's doing the measuring? In fact, who is the buyer in this kind of transaction?

Measuring your l33t sk1llz

In the first place, we all know that it's pretty hard to tell how good one programmer is from another. Sure, it's sometimes pretty easy to assess ourselves relative to one another. Obviously David Hanmeier Hansson is easily more skilled than my kid sister. He's certainly better than I am... but am I better than my colleague in the next cubicle over?

I like to think so and I'm pretty sure that my paycheck says so too... but I'm only guessing that... and is a paycheck a reasonable guide anyway - or is that just a cue for a feedback loop?

A year ago I was working for considerably below the average salary[2]. Partly it was because I valued job-security (and thought I had it[3]) but I've been trying to figure out the other part. Why is it that companies with certain types of management don't offer more to their IT workers? Contrariwise - why is it that some companies hire idiots and pay them huge sums of money?

There was a Paul Graham article that explains that the average PHB can't tell if a technology is really good or not. They simply don't have the requisite experience to make an educated distinction.

By corollary, they also can't tell if the technology skill of their workers is really good (after all, if they don't know how to use it, how can they tell if *you're* using it to the best advantage?). The only clues they have to go on are the skills that they can see and judge from their own experience. These tend to be more socially oriented: is the worker well-dressed, articulate yet polite, well-behaved, do they show due deference to the PHB, do as they're told etc. The average PHB can measure these hirself, so they get put to the top of the list of required "professional" skills.

The skills mentioned above may well be a good indicator of whether or not they'll get along well with the manager, but they are clearly not a good indicator of skill in IT.

Now, I'm not saying these skills aren't important. Doubtless, most of these have their importance in a workplace, especially where one must get along with peers. Without any level of skill in the above list, friction will eventually ensue... and yet the original point here was not to tell how good an IT worker would be at making friends in the workplace, but how good they'd be at being an IT worker... and surely actual IT skill should rank up there as an important part of the job requirements.

Now, a good, skilled techie may know reasonably well how they stack up compared to other techies (s)he's worked with - at least within a few degrees of freedom). They tend to know that if they hand a tough task to Jo she'll get the job done quickly and elegantly, but hand it to Sarah and she'll need a fair bit of hand-holding so you'd better give her the easier tasks while you get on with the "real work".

A less-skilled worker, by contrast, may not have a clue how good they are, and you can't compare at all if you've never worked with a person[4]

So maybe they can tell, roughly, by contrast, their own level of skill - maybe it's not accurate, but they've probably got some idea of where they think they stand. In any case they have information that the PHB doesn't have... and, come review time, every worker will say they are a peach - especially if they're a lemon.

And those that have better social skills will be more convincing to the PHB.

What does the PHB think?

Now, a manager that was actually skilled in IT (eg one that had "come up through the ranks") might have a chance to judge accurately. This neatly slams up against another perpetual problem of the IT trade: that if you promote your best IT workers into management - you are wasting the IT skills that made them good in the first place. Not to mention the fact that to be a good manager requires a completely orthogonal skillset to being a good IT worker.[5].

Of course, if promotion is based on IT skill - you're in a chicken-egg situation. How do you judge good skill to promote if you cannot trust the skill-judgements of those around you? Paul Graham calls this "the design problem".

What does this mean for an organisation?

In my experience, the problems from asymmetric information are amplified in monolithic IT organisations (eg the IT departments of banks), which nurture this kind of manager - and also seem to nurture a higher percentage of mediocre programmers.

If a manager cannot tell if their workers are skilled or not - they aren't prepared to pay as well - after all, the worker might really be a lemon, just saying they are a peach. But a real peach may know that they are - and thus won't be prepared to take the low pay... so they have no choice but to leave. Everyone loses.

This is a self-perpetuating cycle. I don't know how it all started, but you can see that it'd be nigh-on impossible to break out of. A mediocre manager would not be prepared to offer competitive pay to his employees - as he's simply not prepared to pay peach prices on the offchance of buying a lemon. This causes all the actual peach epmployees to leave - they know they can get better pay elsewhere... leaving only the mediocre programmers (and lemons) behind in the monolithic organisation.

Which leaves only mediocre pickings for employees to rise through the ranks to become mediocre managers themselves one day... or the hiring of managers, but without the benefit of a sanity check on IT skills from the employees. In any case leading to generally the same cycle - bad managers, bad employees - lemons all round.

Thus the monolithic organisations fail to get or keep good staff, and the only place to find them is in the small, agile development houses, or in contracting - where a peach can have a chance of negotiating more directly with clueful people.

Which matches what we see around us every day...

Is there any way out of this for large organisations?

Not really sure it's possible. I know some do - but my gut feel tells me this only occurs by chance. If they happen to stumble across a peach by accident, or if one decides to take pity on an organisation and work at making it a better place. But it certainly doesn't seem to be the norm.

The only cases I've really known are where peaches don't know their own worth and stay on, thinking they are worth less than they are. In a mediocre organisation this might last for a while - as their worth is determined by people who don't know how to accurately judge worth. But eventually a true peach will learn about themselves and leave - usually by going outside of their colleague-group and seeing what other people are acheiving in their field - ie by getting a better frame of reference.

Any opinions?

Notes

  • [1]By Tim Harford - pretty good read, actually.
  • [2]for a programmer with my experience - as measured by two different salary surveys. Note: for australia many IT managers use the Hays salary survey which is great... except that it leaves job titles somewhat vague - and several of them don't specifically have a "years experience" associated with them (especially the oft-misunderstood term "junior developer"). When going for your pay review, I recommend searching for a variety of surveys - and make sure they have years on them.
  • [3]...an entirely different story that I won't go into here.
  • [4] Paul Graham wrote an article about Great Hackers which also discusses how it's hard for hackers to judge the abilities of other hackers without having actually worked with them.
  • [5]It is not impossible for a worker to have both sets. It is more rare, however, as a skillset takes time and effort to develop... and your IT workers are generally spending more time developing their IT skills than their social ones.

Wednesday 12 December 2007

Rails 2.0

Ok, so Rails 2.0 is out - in case you somehow missed the wild whooping sounds from the Rails community.

At the following site is a comprehensive list of changes in Rails 2.0. Worth studying a few times.

Tuesday 11 December 2007

Rails gotchas: Update attribute... doesn't

Ok, it does... but it doesn't *just* update the attribute - it resaves the whole record. This is a problem if you aren't sure whether or not your record is fresh as you can overwrite other changes with your stale data.

Lesson:

As nasty as it is, you should do a do a self.reload before you do an update_attribute - if it's possible that your record has changed under you (eg by a called sub-method)

Thursday 6 December 2007

Rails Gotchas: fixtures created_at when?

So - I updated some date-sensitive fixtures and re-ran all my rake tests... and suddenly everything went funny.

First off the rack: empty created_at date

The first problem seemed to be that the created_at date just didn't get set at all. I even printed it out in my test case with an "inspect" and it was showing: "created_at" => "0000-00-00 00:00:00". Pretty nasty.

I checked the fixture and even printed out the date I was trying to save (Time.now.utc) to make sure that Time was working in the fixtures... to no avail, until I realised I'd accidentally knocked off the .to_s(:db) from the end. I added that back and magickally my fixtures were loading the dates again (yay).

Next up: intermittent wierdness

So then there was an intermittant, but persistent error that was really weird. The method I was testing boils down to me pulling out a set of objects and ordering them by creation-date and checking the value of the last one in line. I was checking that if I created a new one - I actually got the new value out the other end. Now the problem was - sometimes I did... and sometimes I didn't... sometimes I'd run rake-test and it'd work... and I'd run it straight afterward and it'd break again.

Then I remembered that datetimes only have a one-second granularity... and some of my tests probably ran less than one second after setup. So I used 1.second.ago.utc.to_s(:db) in the fixtures and it all went away. :P