Lolspeak in The Gap and Lowly Passengers

The Gap, now in Lolspeak:



Unrelated: why do passengers not deserve a single capital letter, when almost every other word does (Alameda ferry)?

Mozilla: Please Fix This

All the tools I use professionally are open source, with the exception of MS Office and Visio. My browser is Firefox, my email client is Thunderbird, and I manage my calendars with whichever calendaring program wasn't abandoned by Mozilla. By and large Mozilla software it's pretty good. It does the job very well much of the time, and competently almost all the time; but I do wish Mozilla had a little more UI sense and discipline to make better, clearer choices in their product development.

Tabs, Tabs, Everywhere
Thunderbird makes a big deal of its tabs. "Now with tabs, better search, and email archiving" is the main selling point on the download page:

Now, I'm all for innovative UIs, but did the world really need tabs for email? Email has been around for decades, and mostly mainstream for 15 years. Most consumer desktop programs open a new window when you open an email. It's pretty much the standard paradigm for desktop clients; web and mobile clients are probably making this paradigm semi-obsolete, but millions of people use desktop email programs every day, so it's not dead yet. And I don't think tabs are the way to go for email.

Sure, you could make the same argument about browsers: before tabbed browsers started gaining market share, new pages opened in new windows, but tabs have proven themselves as a superior alternative for many people. No argument from me; I used a tabbed wrapper around IE back when Firefox (then Firebird) was more unstable than Jeffrey Dahmer. But a browser has one primary function (viewing web pages), whereas email clients have a long history of letting you manage more than just email, with calendaring, to-dos, notes, and various other things. And that is where the tabbed design breaks down, and why emails shouldn't be opening in tabs. Note I don't expect the Mozilla people to read, care about, agree with, or implement any of these suggestions; after all, it took them years to fix the horrible usability error whereby you couldn't disable the functionality that marks emails as read when displayed in the preview pane. This is the one problem that prevented me from using Thunderbird as my email client. It's now an option, and disabled by default, if memory serves--thanks! But I'm going to gripe^H^H^H^H^Hwrite about it anyway.

It's a pretty common occurrence for me to get an email trying to set up a meeting, with "Does Thursday at 3 work for you?" That's not exactly convenient if you use Thunderbird for calendaring with the Lightning plug-in--now you have an email in a tab, and your calendar in a tab, and so you can't look at them at the same time. You can't alt-tab between them. You have to be keyboard-savvy enough to know that ctrl-tab is how you flip through tabs in a tabbed MDI program. Opening an email in a tab is also not as dramatic visually as opening a new window, so it was pretty frequent for me to open an email multiple times because I hadn't seen the new tab.

Tabs work well for distinct top-level features in Thunderbird: email, calendar, notes, to-dos, etc. Using tabs for sub-features of any of these breaks the hierarchy.

To their credit, Thunderbird lets you disable tabs for email, and that's the first thing I did, but it shouldn't be the default.

Drag Queens
While on the subject of Thunderbird, when dragging attachments onto a message window, why does the main message body not register the drop, while the "To:" section does? What kind of sense does that make?

Conceptually, the attachment is closer to the body of the message; it has nothing to do with the recipients. I understand why the whole address section is a drop target--that's because the attachment summary opens a little square to the right of the address section when you've added an attachment. But that square is nowhere to be seen until you've added said attachment, making it very non-obvious how you're supposed to attach files, especially if you've tried to drop a file onto the message body and failed. Come on, folks, this isn't hard. Get it right.

Tangent #1

Speaking of drag and drop: why do bloggers and web content creators still put up with the pre-2000 model of having to explicitly upload their photos via a dedicated upload form, and (if they're lucky) move it into place in their rich-text editor? Why haven't enough smart techies come up with a standard way to let people just drag a photo from their desktop onto their rich-text editor and have it show up in the right place, without having their text reflowed or mangled beyond repair?

I know the technical answer; what I want to know is why people aren't angry enough about it to demand a fix. Software should be transparent; exposing the nasty technical guts of the software by not providing an integrated experience is a sad cop-out, and the web community should do better.

More T-Bird

While on the topic of Thunderbird, another little thing that wouldn't hurt is to add a little intelligence into the parsing and display of the email. Apple's terrible Mail program does this remarkably well by automatically highlighting words like "yesterday" and "tomorrow" and showing a context menu to create events in their otherwise execrable iCal program; it also highlights contact information like phone numbers detected inside an email.

What I'd like Thunderbird to do is be a little smarter in the message display. When someone receives a message and highlights a section of it, then right-clicks on it, why not show a Search for xxx in your browser (using the default browser and search settings)? Even better: if you can detect that the highlighted string is an address, add a link to a map (a Google map would guarantee even more money for the Mozilla foundation); a phone number? Show a context menu to add it to your address book (together with sender's name and email), or overlay the contact's info if you can find it in the address book.

Yes, I know, I can edit the code myself and probably finagle my changes into the trunk, but why should I have to?

Pick One
One last gripe: I wish the Mozilla folks would just focus a little.
Why have plug-ins, add-ons and extensions? Why even use that awful phrase "add-on", when "extension" is pretty clear (extensions extend the basic functionality, get it?) and a lot less techy? Similarly, why have both themes and personas? And why have Firefox, Seamonkey and Camino? Why not call them Firefox, Firefox Suite and Firefox for Mac, if you must distinguish, since they share so much of their rendering technology? What are the differences within those product families? Is there a difference? Most importantly, why should the end-user care?

With double-digit market share, Firefox isn't the bailiwick of basement-dwelling, Gentoo-compiling geeks anymore, so the old hyper-specific tech terminology needs a revamp.


Twitter: Unsafe at Any Speed

I'm a very light Twitter user. The value of the service is still mostly alien to me. And on the rare occasions I log on (or try to) and post something (or try to), something doesn't work.

I've actually been keeping track and found that Twitter breaks on elementary, "mission-critical", sine-qua-non functionality (like logging on, posting a tweet, or refreshing your stream; not the fancy stuff like uploading a photo or anything--I'm talking about operations without which there is no Twitter service) a full 66% of the time (that's two out of every three times I log on to Twitter).

I know scale is hard, but with over $150M in the bank and tech people begging to work for them, you'd think they'd have the absolute basics whaled nailed and rock-solid by now. As it is, they have more in common with my old 1983 Plymouth Horizon and its lovely (un)planned obsolescence, except people are treating it like it's a gold-plated Veyron.

Even their log-out functionality is broken right now:

I'll readily forgive a brand-new startup site in beta built by 2 unpaid engineers functioning on espresso and Red Bull throwing out erroneous 403s occasionally. But a supposedly major consumer site with $160M in funding, ~330 employees (as of 11/18/10), and dozens of engineers and operations people, trying to paint itself as a major force for marketing on the internet, at 11pm PST on a Thursday night? I don't believe for one second a technical staff that big, hip and passionate about their product is stupid, careless or incompetent--I'm just baffled. And yes, Twitter is big and has novel scale problems, but they're not the largest site on the web, and I don't remember a single time when google.com failed to perform a search or display their home page. Do you?

I know the world has gone completely insane about Twitter (another round of funding at a multi-billion-dollar valuation is supposedly in the works), but these guys seriously need to stop screwing around and solve their two biggest problems (stability and monetization) once and for all. Until then, I'll keep fail-whale-watching with the other haterz.

Encouraging Piracy, Part XLII

Queuing up a video on Hulu, I ran into this absurd notice:

Why should I be able to watch this video on my computer but not on my iPhone, or Hulu-enabled TV/Blu-Ray player, when I can watch other videos on any device? Why can I stream some shows on Netflix, while others require a physical DVD to be shipped to me? What kind of sense does any of this make to anybody? Restricting access in any way (not just to some arbitrary collection of devices) means smaller residual checks for actors, fewer royalties to the studios, fewer opportunities to display ads, and pissed off users who just want to watch a show. Everybody loses. The display device should be completely irrelevant. This is just as absurd as a book you can read in bed or on your sofa, but not on a beach chair or a commuter train. Or a CD that can only be played on players approved by the manufacturer. Nobody would do that sort of thing. Right?

In the meantime, people who download torrents get their content quickly and can watch it whenever, wherever they want, on any device they own, unencumbered by meaningless, arbitrary restrictions.

Other than the Soup Nazi, I can't think of any business that is so obdurately hostile to the people that support it financially. Doesn't anybody in the entertainment industry realize they'll keep shrinking and alienate everyone around them for as long as they make piracy the most attractive method for accessing their content?


Lying with charts

Charts can be very useful for capturing complex data and making it understandable. They're also very easy to use maliciously (or stupidly) to mislead and dramatically exaggerate differences. This chart (source) is such an example.

The leftmost green bar is 362 pixels tall, with a fairly tall point at the top. The rightmost blue bar is 52 pixels tall, with a somewhat flat point. This suggests the site with the green bar (a nice, warm, winning, "green means go" color) has almost 7 times as much traffic as the site with the blue bar (a cold color).

But if you look at the actual numbers at the top of each bar, you'll see that the short bar (6.149M) is only 2.3 times shorter than the tall bar (14.340M). That's because the y axis conveniently doesn't start at zero. The net effect is a 3x magnification of the actual difference. Yet the chart maker can still safely claim they're not lying, and indeed they're not--the numbers are right there, undoctored, for all to see. But the damage from the giant visual difference is already done.

Shrinking the scale of a chart like this so it doesn't start at zero is dishonest. Chart junk like fake-3D bars with taller pointy tops on taller bars only makes it worse. Zillow, you should be ashamed of yourself. Maybe your chief economist could come forward and disavow this piece of agitprop for what it is.

Disclosure: I led Trulia's Data Services team until August, 2010. I no longer work there, but still work on producing accurate data that informs and doesn't lie.


Cloudera Hadoop training

I just attended a three-day Hadoop training course and learned a lot. Glynn is a very good instructor and knows the system very well. I strongly recommend the course to anyone interested in writing data-processing software built on Hadoop (I didn't attend the system/operations session, so I can't speak to its usefulness to ops folks). And not just for the course materials, either, because so much of it is already available online: it's a great opportunity to block out three whole days to focus on learning a new technology, and that's not something I've been able to do since graduate school. So yay for the course, and yay for my employer for seeing its value and sending two of their engineers to learn new things.

Speaking of my employer, maybe you are or know someone with experience in data processing, data warehousing, Hadoop and similar technologies? If so, let me know.

(yes, I took the certification test, which was harder than Glynn had led me to believe, and passed) (yay)


On Open Systems


The technical and societal significance of open systems in general and the free software movement in particular crystallized in an interesting light for me the other day.

During a recent conversation with another techie, we discussed the rapid emergence of Big Data, large-scale data processing and analytical insights that were once completely out of reach.

Then she asked me,"Why do you think this is happening now?"

A Simple Question

That simple yet pregnant question was not something I had pondered before, and yet an answer came very quickly and naturally: the free and open-source movements, or rather the free and open-source mindset, made it possible.

One major benefit that free-speech OSS brought to society was that it started millions of conversations on what to do, how to do it, and more importantly how to do it better, faster, and more securely, without any of the shackles of commercial software development. If your open piece is better than mine, I'll just put it into my product and make it better for the rest of the world. Without this openness and instinct to share ideas publicly in order to get at a better, more thoroughly vetted idea (aka standard), this extraordinary accomplishment known as the internet, which all of us are still in the process of inventing on a daily basis, would simply never have happened.

Hardcore GNU folks often pooh-pooh the importance of the free-beer part of F/OSS, because of their higher ideal of freedom and openness. But I think that's misguided. Free-beer OSS made it possible for millions of people to learn software development because they didn't have to choose between paying the rent and paying for a software license for an operating system, database, programming language, or IDE. They also didn't have to pay a dime to learn those languages, because OSS extends beyond software to free downloadable books, tutorials and help manuals. Where would computing be today if it weren't for those computer scientists, software developers and other technologists for whom free-beer learning was the only option?

Combine those two general benefits and you get to a point where a huge number of people write massive amounts of high-quality software to handle interesting, complicated ideas that goad hardware manufacturers into ever-faster progress on ever-cheaper devices, and you get to a critical mass of mental energy and pervasive hardware availability (read: large stacks of cheap computers) that gives rise to a true step change in how much we can do, how many questions we can answer, and how quickly and cheaply all of this can be achieved.

Open and Shut

That's not a factual, falsifiable answer and I'm not claiming to hold any deep scientific understanding of the truth about the state of computing circa 2010. But whatever one's opinion on the matter, I'd still say freedom, openness and community-driven standards in software and hardware development played a big part in making the computing world better, and so the real world.

Another way to put it, with all due respect to a great businessman and technology visionary who's still the exemplar of secrecy par excellence and won't embrace the virtues of openness: if the human body hadn't been jailbroken, Jobs wouldn't have a new liver. A bad deal for everyone.


Remove Twitter from Google search results

If you (like many others) like your Google search results unencumbered by the Twitter scroller Google added a while back, paste this into your browser's address bar:

javascript:(function untwit(){var r=document.getElementById('rtr');if(r){r.parentNode.removeChild(r);}})();

You can make that into a bookmark, name it "untwitter" and save it in your bookmark toolbar. You can then click on the bookmark to remove the scroller.

Only tested on Firefox 3.6.



If I Had a Hammer

It is sometimes said that software makes difficult tasks easier. Often the task is difficult not because the problem being solved, or the question being answered, is difficult per se: "I need to know when our users are likely to cancel their membership so we can send them win-back promotions" is a well-formulated, easy-to-understand, bounded question, and the answer is likely to be equally finite and easy to understand. The difficulty lies in gathering, compiling, and analyzing vast quantities of data in a timely, repeatable, reliable manner so that 1 billion data points coalesce into a half-dozen usable pieces of information. That's hard, and intractable unless you can process gobs of stuff really, really fast. Computers, and good software engineers, are really good at this sort of thing, and by and large you can never have enough of either.

All Nails

But a rampant trend in tech companies is the tendency to resort to technology and software to make easy tasks difficult.

Imagine a meeting room filled with 20- and 30-somethings, all endowed with solid educations, a solid drive to do the right things, and the disconcerting ability to explain the difference between TCP and UDP to finance people. The topic at hand: how to foster new ideas, team spirit, information exchanges, the kind of collaborative awesomeness you can sometimes get out of enlightened corporations and smart, enthusiastic people. The conversation might very well go like this:
"How about we set up a wiki page so everyone can contribute ideas and see everyone else's ideas? It's be really transparent and easy."

"Good idea! Once the ideas have coalesced a little, we can use Basecamp to see who's working on what and have real flexibility so new people can jump in and grab tasks they're passionate about without a big formal team structure!"

"Awesome! And since everyone's laptops have webcams, we don't need to have those big meetings--we can do ad-hoc catch-ups over Google Talk without everyone having to be around the office."
Those are all good ideas, and they would probably work for the project you're all working on. But when your entire team is reaching for ways to do things that wouldn't work during a power outage, or were not even remotely possible less than ten years ago, maybe it's time to take a step back and reassess.
"How about we just stick Post-Its on the wall over there?"

I don't believe this kind of tech-centric groupthink arises out of malice or a perverse instinct to complicate--my money is on a combination of habit (we use our computers during most of our waking hours), a tacit post-industrial rejection of the trappings of the Old Way of Doing Things, and recency priming effects (the last thing most people used before the meeting started was a computer program reminding them they were supposed to have interactions with other human beings). All those factors conspire to obscure other modes of communication and collaboration so ancient and universal they simply blend into their environment, devoid of shiny surfaces and sleek contours, waiting to be used.

Tool Envy

I personally don't share the fetishism for tactile, low-tech (and wantonly expensive) implements so prevalent among financially independent Bay Area techies. It's tempting to ascribe this post-modern stylomania to the scribal equivalent of comfort food: in a fast-moving, high-tech environment, non-electronic utensils like #2 pencils and tidy notebooks with elastic bands to prevent intempestive openings provide the stressed techie with a familiar anchor to long-ago times when things were less complicated and responsibilities less burdensome, redolent of chalk and crayons and cookies and blood from one too many encounters with Jimmy the football player now safely stowed away in detention. Or possibly something phallic.

But when it comes to getting ideas, moving them around into thematic buckets, discarding the bad ones (physically!), refining the fuzzy ones, and making them available to everyone, passively visible at all times, omnipresent and inevitable in their glaring obviousness and gaudy magenta-on-high-gloss-white, nothing--nothing--beats Post-It Notes and Sharpies. Even the hard-to-read ones are useful, because they draw you in and make you think about what they might mean.

A Web-accessible company intranet / wiki / bulletin board is undoubtedly a very convenient way to share ideas with everyone--it's dynamic, accessible from anywhere at any time, and does away with any requirements of physical co-presence that the modern office tries so hard to make obsolete.

But unless you're crazy and never close any tabs in your browser, you probably don't have that project wiki open in front of you all the time, and it takes an active effort to be engaged in the project. By contrast, the cadaverous whiteboard and its bright pimply scribbles is both easy to ignore, like a light fixture or a garbage can, and impossible to avoid, by virtue of its large, immovable presence; walking past its hodgepodge of colorful puddles instantly draws your gaze and reminds you there's something interesting going on, without your having to do anything.

As for the additional benefits (constant, virtual availability)--are they solving a problem you actually have? If most of the collaboration happens between people who can reasonably be expected to be in the same place during overlapping business hours most of the time, do you really need 24/7 remote availability of your idea board? And if someone really is available at 3am, maybe what they need is a reminder to go to bed rather than a tool to help them work in the middle of night.

Rampant Complexity

This tendency is hardly the bailiwick of 21st-century internet startups. Take One Laptop Per Child for example: an interesting, beneficent idea, to be sure, but it seems to me investing in mosquito nets, immunizations, education, human rights and safety for every child in the developing world may cost less, be more immediately useful, and go a bit farther than giving a crank-powered Linux computer to a bunch of kids who could really use some clean water and the assurance they won't go blind before they finish reading their first book.

Beyond computers, the 1980s brought tremendous technological advances to musical instruments: synthesizers became mainstream, and piezo-electric pickups made it easy to amplify and record acoustic guitars--so easy, in fact, that the world collectively agreed to ignore their atrocious sound and to forget that sitting down in front of a single microphone really isn't all that hard.

Snatching Simple from the Jaws of Difficult

Note that this is not a paean to the Luddites. My main computer has a modern dual-core processor with obscene amounts of memory and more hard drives than I remember, because larger, separate hard drives mean worrying less about backups; but it's attached to a pair of giant 10-year-old CRT monitors, because the productivity and eye comfort of 3840 x 1440 vibrant, never-stuck pixels outweigh the benefit of lightweight, space-saving LCDs--the last time I physically had to move my monitors was over 4 years ago; space and weight savings are nice to have, but completely irrelevant.

I store recurring shopping lists into my phone (e.g., lists of hard-to-find books for the occasional bookstore trip, just in case), but jot down grocery lists on envelopes out of the recycle bin, because their useful life span (minutes, hours at the most) simply does not justify spending more than a second or two jotting items down. As long as I can scrawl "milk" faster than a phone, computer or PDA can wake up from standby, launch the shopping-list program and fix my virtual-keyboard typos into a sensible word, technology is a hindrance, not a solution. Sure, I could integrate the two lists and sync them to my Google account and set up reminders to buy Kleenex via SMS before I leave the office. But I have better things to do with my time.

Microsoft didn't come up with Sharepoint out of sheer boredom, perversity, or greed. Mailing Post-It Notes around doesn't scale very well if half your team is in Los Angeles and the other half in Manila. Of course technology is the right approach a lot of the time, maybe even most of the time. But if technology is good for many things, it's not necessarily good at them. Weigh the actual (not the hoped-for, or potential) benefits of using one method, against its implementation, evangelism, training, and maintenance costs. Don't pick a solution based on its ability to solve a problem you don't have, or almost never have. The burden of proof is on the complex approach, not the simple one--simplicity should always win unless there's a compelling reason to go the other way.


Looking For A Job?

Looking for a job isn't fun. You have to boast of your accomplishments, which some find distasteful; you have to repeat yourself a lot as you send out your résumé and ever-so-slightly customized cover letters all across the internet, which some find tedious; and you have to do all this while in the throes of unemployment (or on the QT while still employed), which nobody enjoys.

It's no picnic for the hiring manager, either, especially at start-ups. Managers are usually expected to do other things than manage--lead engineers are supposed to code, VPs of marketing craft email campaigns, UX directors whip up Photoshop designs, and so everybody is chronically strapped for time, not least the person in charge of coordinating 30 positions that need to be filled yesterday without completely ignoring the existing employees and their ongoing issues. You have to balance the supreme requirement of hiring the right people (i.e. being ruthlessly selective) with the urgency of the hire and the overhead of screening, interviewing (and rejecting) a non-zero number of candidates. It's pretty common to find yourself in the following paradox loop:
"We need to find a (programmer|designer|marketer|PM|salesperson) pronto or we're never going to (ship|sell|market) this thing this year"
"I really don't have time to (screen|interview) those applicants"
I've been privileged to participate in hiring a lot of great people over the years, either as an interviewer or a hiring manager; and because I've been knee-deep in résumé-screening trying to fill a couple of positions for a little while, I thought it might be useful to recap a couple of the hurdles applicants and hiring managers always seem to be running into.


One of the hiring manager's more enervating enemies is the job trawler. The job trawler applies for dozens (hundreds) of jobs at the same time, with little regard for the posted requirements, presumably in the hope that the hiring manager will take it on faith they can learn the skills on the job, or not notice they just filled a real-time embedded-systems development position with a JSP programmer who's never even heard of C.

To spell it out in simple terms:

"Requirement" means "you have to know this stuff"

and so this:
"Requirements: 4+ years Oracle, PL/SQL, 6+ years C++, excellent knowledge of Unix/Linux performance optimization"
means that this won't cut it:
"Skills: Java (2 years), MySQL (3 years), perl, Windows Server"
Applying for a job whose requirements you don't meet is worse than ineffectual: it's counterproductive. It sucks up time out of a busy person's schedule that they could be spending interviewing qualified candidates. And if they have a modicum of organization, they might remember this when you apply for another position at their company.

Don't do it. And for Pete's sake, if the hiring manager sends you a rejection letter telling you you don't meet the requirements, don't argue with them.

Let Me Show You My Pokemans

Spelling, grammarsilly kitties and punctuation are mostly arbitrary and capricious. That's partly why software developers came up with various devices to help supplement their fallible memory (or typing skills), such as spelling- and grammar-checkers. Many are even free. So when you send in something like this:
dear mr/msr,

i wanted to apply for the engineer position in ur compny on craigslits i am a hardworking programmer with 2 yr. experience in java technologys. i guarante dedication to ur company because i need the money so i won't let u down.

  • java, j2ee, jni, xml, soa
  • well communication skills
  • work good under pressure
i look forward to discuss my application.
it just doesn't make a good impression, and when a hiring manager is screening résumés to find candidates that are worth spending over 10 man-hours wooing and interviewing, your first impression is all you have. Maybe Donald Knuth, Brian Kernighan and Ray Ozzie are ready to be your references at a moment's notice; maybe you did write seven bug-free patches that got checked into the kernel tree; but if your résumé and cover letter look like a Scrabble game board after a tornado, you'll never get a chance to show off those 1337 skillz, or to get Knuth on the phone with your boss.

There's nothing wrong with not having a hypertrophied command of English. There is, however, something wrong with not turning on your word processor or Web browser's spell-checker, or not spending 10 minutes going over your application materials to make sure they will impress your future boss into calling you in for an interview. If you're in school, visit the career center. If you're employed, ask a trusted co-worker (or your boss, if you can). Librarians love to help, and they're often the hyperliterate type that can smell a typo from a mile away. It's a cheap investment with very high returns.

Stating The Obvious

Of course, all of this stuff is trivial and should be self-evident. Joel Spolsky has written at length about it; he even started a job board. If you're like me, you want to hire people who read Joel Spolsky, so it's extra disheartening when so many of the resumes that come across your monitor show no evidence of Spolsky-awareness (or common sense).

In the case of software engineering jobs, in particular, you'd think people with the brains, education and experience (nominally, at least) to go after a job that can bring in six figures pretty quickly1 wouldn't even have to be told these things.

Rejecting a candidate is not something hiring managers do lightly: the opportunity cost of not hiring a great candidate is high; and we've also all been in an applicant's shoes, so we know how hurtful and discouraging it can be not to be called in for an interview.

So if you're a hiring manager, make sure your job postings and requirements are clear, follow up with applicants (both good and bad) in a timely manner, and renounce the "Screening applicants is such a time sink" attitude. If you're looking for a job, stack the odds in your favor, don't apply for jobs you're not qualified for, and knock 'em dead with a crisp, punchy résumé. And if you're a database or data warehouse engineer, get in touch ASAP.

1. If you're reasonably good at it.


Breaking the Unit-Tests-Take-Too-Long Cycle

Unit Testing in Theory

By now (2010) every experienced software developer worth her salt has heard about unit testing. If you're not familiar with the concept, here's how it goes in a nutshell, using some fake programming language:

class Thingie
public static function do_something(param)
if (param == 0)
return false;
c = new network_connection();
data = c.fetch();
return !empty(data);
class ThingieTest extends TestFrameworkTestCase
public function test_do_something()
T = new Thingie();
this.assert_equals(T.do_something(1), true);
this.assert_equals(T.do_something(0), false);

TestFramework ThingieTest

1 test, 2 assertions, 0 failures.

Many languages have unit-testing frameworks available. Unit testing is an elegant, systematic, automatable system that makes obsolete all the ad-hoc programs developers often write to test various parts of their code. The field is both fresh and mature enough that there's a small, well-known set of standard practices that make it easy to start writing unit tests in language A if you're familiar with unit tests in language B. By and large, it's a great invention with considerable benefits.

Some have embraced the practice and follow it almost religiously, writing their unit tests first and actual software second. Others apply unit testing more like salt, pepper and nutmeg, as needed but not in excess. Still others write tests reluctantly and need to be reminded frequently, like patients chided for their infrequent flossing by their dental hygienist. And others just write code and custom test scripts (I actually know superlative software developers who've never written a single unit test and probably never will). You may find that a developer's attitude towards unit tests has some relation to the year they started getting paid programming gigs.

Unit Testing in Practice

The majority of developers I did, do, may, will, and won't ever work with, interview and hire probably fall in the unit-tests-as-spice camp: they're reasonably convinced unit testing is an excellent insurance policy, they may even evangelize the practice with unenlightened colleagues, but they readily admit their unit test coverage is spotty or out of date, with a curious mix of rational self-confidence ("I try to test code that's important, not getters and setters; 100% coverage is silly") and underflossed guilt ("I probably don't write as many tests as I should"). I'm certainly one of them.

A lot of (most?) software shops put a lot of pressure on developers to just crank out code that does something. As a result, software that doesn't do anything visible gets short shrift if it gets written at all, and unit tests are often the first to get the axe. Oversimplifying, the tacit (and circular) rationale looks a lot like this:

  • a good developer's best code is bug-free
  • bug-free code will pass all its unit tests, by definition
  • therefore, writing tests is a waste of time, since they won't uncover any bugs
Making Tests Work

A common strategy to encourage beneficial behavior is to wrap the hard-to-do stuff inside something they normally do: hide a cat pill inside a yummy treat, or stick a tongue-scraper on the non-bristly side of a toothbrush head. Brush your teeth and clean the rest of your mouth at no extra charge!

Similarly, the benefit of unit tests can be self-sustaining if you can make your tests:

  • run as often as necessary
  • run at no cost to the developer
  • draw attention to their usefulness very forcefully when something breaks
  • remain invisible otherwise
This could mean suppressing all output when all tests pass, but warning the entire development team when a check-in is going to break the build so the bug can be fixed immediately rather than rot in your bug tracker's entrails, forgotten until your boss demos your product to the board, trips the bug, and sends your entire team into a panic trying to hot-fix the problem in the program QA signed off on two hours ago.

Here are suggestions to increase your team's enthusiasm for, and the effectiveness of, consistent unit testing. All of these tips are some variation on the parasitic-benefit approach outlined above.
  • trigger your unit tests automatically using a pre-commit hook in your source-control system. Every time someone tries to check in her code, all your tests run automatically, and any failure blocks the commit. You have to fix the code (or the test) before you're allowed to check in your code.
  • trigger all your tests automatically, including your integration tests, at the top of your release or build script. The release or build is blocked if any test fails.
  • use a bootstrapping framework or wizard to generate boilerplate code, including matching unit test code, for every class you write. The less code you have to write, the more time you have to work on the good stuff. Ruby on Rails or Django are such bootstrap systems; they're easily extended to add boilerplate unit test code.
  • have your unit tests create persistent, semi-random test data in your dev database. Every time you run your tests, you get more data in your development database, which makes your application more realistic during testing and can uncover issues you only run into under actual use conditions (e.g., you might realize what a mess your UI is when it tries to display 250 items on a single form).
  • have your unit tests obliterate the test data in your dev database every time they run. This weans you from over-reliance on test data, which can be handy if you're shipping a brand-new product with zero user data on launch day: you consistently get to interact with the same product your early users get to see on day one. Yes, this is exactly the opposite of the previous point; use your judgment.

There are many other approaches, including forgoing unit testing altogether, and sometimes that might be just what the doctor ordered. Don't be afraid to try new things, nag at your colleagues (not too much), drop what fails and pursue whatever works for your product and organization. And by all means share your experience--open-source processes are just as vital as open-source software.


Make Sure Your Customers Can Pay You

If you're running an e-commerce site, chances are you want to extract money out of your visitors. Yet you wouldn't know it by looking at some sites like Best Western's reservation portal, which makes it incredibly difficult if not impossible to complete a paying transaction, as I recently discovered to my chagrin.

Invisible Form

Here's what happened: after selecting a date range, I pressed the big giant "Book it" button next to the room I was interested in (+1 for using big huge buttons for the primary action):

This led me to the following page, completely devoid of a form into which I could enter my credit card information:

After another failed attempt, I fired up Internet Explorer to see if the form was crucially incompatible with Firefox, and I got my answer: the credit card form is served in a popup window, which IE requested permission to open and Firefox quashed silently (I have the "be quiet about popups" setting turned on). Here's what it would have looked like with slightly more verbose Firefox settings:

Note that no one using a reasonably recent browser in its default settings gets to see the popup window unless they explicitly authorize it. In other words, one hundred percent of Best Western's juiciest, readiest-to-buy visitors are not shown the reservation form in the default use case.

I don't have to spell out how completely crazy this is.

To make matters worse, when you do complete the form and click the submit button, nothing happens in Explorer due to a javascript:void(0) issue in the form submit handler1; in Firefox, the window simply closes with no confirmation the transaction went through.

I had to call the hotel to find out how many of my three form submission attempts had gone through (one had, which was soon confirmed by an email from the site).

Money For Nothing And Tests For Free

What this tells me is that the designer(s) and developer(s) in charge of the Best Western portal never did so much as basic hallway usability testing before they shipped their product. Maybe they don't know about it; maybe the product team is in Connecticut and the developers are in a different country. Either way, a 30-minute investment would have caught what is potentially costing the company tens of thousands of dollars a day.

Another notable omission is that the credit card form itself (for those of you lucky enough to see it) doesn't exactly scream "GIVE ME ALL YOUR MONEY NOW!" I'd bet its conversion hasn't been tested or optimized either.

Testing form conversion is hardly a novel or esoteric branch of rocket science; it's a simple, mature field with well-known best practices and automated testing systems to help you get the most out of your site. But a company that can't be bothered to test the basic usability of their purchase flow can't be expected to look at bounce rates or A/B test their funnel.

Given the bang for the buck you get from real-world testing with a tiny number of users, I submit Best Western could have earned an ROI on the order of 100,000% if they had just watched a half dozen travelers go through the booking process using a fresh, default install of IE or Firefox.

Help Me Buy What You're Selling

I will never know how much money Best Western is losing from this; presumably a lot of travelers wind up calling the hotel (whose phone number is displayed at the top) and maybe even pay the (higher) non-internet rate you get when reserving by phone. So for all I know Best Western is actually coming out ahead (I have my doubts).

What's really sad about this grossly inefficient system is that Best Western didn't even have to earn my business: all they had to do is keep it. Given the way RevPAR is trending, that's a gimme they don't get very often. I always stay at that hotel when traveling down south, because it's convenient, well located, reasonably quiet and clean, and its wireless internet occasionally functions. But I don't know how patient I'm going to be next time around.


1. Don't use javascript:void(0) to block a page reload event in an a tag. This will work:

<a href="#" onclick="do_something();return false;">text</a>


The Process

An issue most software shops have to adjudicate at a certain size is how to build applications. Not how as in which languages, servers, or database systems (hopefully that's settled early on, revised periodically, and mostly stable)--how as in how, how early, are features defined and built, how often code is tagged and released, iterative v. waterfall, agile v. see-what-sticks free-for-all, etc.

Small startups comprised of one product co-founder and a technical co-founder usually don't need to worry about this. But as soon as you're big enough to have discrete design, product, customers and QA people involved, setting up the right processes becomes a necessity.

What I'm calling "process" here is the set of practices used to build a software project, not the dreaded product-design-executives-board-executives-design-engineering gauntlet your idea may have to go through before seeing the light of day. Rather, "process" here means the tools, approaches, meetings and other day-to-day activities you decide to use to build your project: daily stand-up meetings, waterfall specs, retrospectives, whiteboards, white/gray/black-box QA, pair programming, whatever. It's a stodgy name for a concept that needs not be stodgy.

Why Process?

One source of friction in software development is that software is malleable, and so tweaking features all the time is easy (and tempting). But one person's flexibility is another's sloppiness; one person's easy last-minute tweak is another's bang-your-head-on-the-table1 nightmare.

When building a bridge or skyscraper, with hard, heavy parts that need to be measured, ordered and fabricated months, if not years, ahead of time, the notion goes that you can't get away with sloppy/flexible/just-in-time/no planning and last-minute changes, and so building software shouldn't really be any different, because sloppy/flexible/just-in-time/no planning makes the product buggy/brittle/ugly/inconsistent. It's a common argument I've heard even from people who would rather mine coal in Mongolia than go (back) to the waterfall model.

But I think that's a bit of a false contrast. While I do expect structural engineers to know what they're doing and plan how they're going to do it if my life depends on it, I also expect them to be agile enough to respond to unexpected conditions, or to incorporate new ideas or technologies that come along when it makes sense (which does happen when you're working on a 15-year project). And I don't know any good software engineer who actually enjoys a 1-year planning cycle before they get to write any code or create table schemas.

The point is that you're usually building something for other people, and so what matters is your ability to deliver a quality product for those people. And change happens. Great new ideas come in at the last minute. Your CEO finds a blind alley in your UI flow nobody on your team had thought about. So complaining about, denying the existence of, or impeding those changes doesn't really gain anybody anything. But to the extent your own comfort or happiness or need for control are determining factors in whether you do deliver a quality product, you need some kind of process to enable you to build the best possible product in the best possible conditions.

Ask What Your Process Can Do For You

Process is meant to get things done well (your customers like your product), quickly (a leg up on the competition), and comfortably (high turnover is the enemy). It's not an mystical spirit or a magical toolbox to be worshiped or enshrined. And it's not the 100-year-old secret formula for Coca Cola or your grandfather's super gooey, always delicious sticky bun recipe, either.

Think of it as a suitcase containing the right outfits for a year in California. If you're spending April in San Francisco, you might want a lot of light layers, with a waterproof shell you can take off easily when it stops raining, and maybe a windbreaker. If you drive up to Tahoe in January, you might want snow mittens and a thick parka. And don't forget a swimsuit and towel for those summer days in Santa Monica. It's not the end of the world when the clothes get stained or wear out; you can take the suitcase with you to your next destination; and when you gain or lose weight, some of your clothes won't fit anymore.

Perhaps most importantly, if you find yourself wondering why people laugh at you and your dorky parka on the beach, or you're uncomfortable in your t-shirt and vest in the snow, the problem isn't with the clothes you're wearing--think about the ones you're not wearing.

Bad Process, No Cookie

It's easier to describe process when it's broken. How can you tell your process doesn't work? Defects creep in, stress rises, milestones are missed, good people quit. Sure, all of those symptoms could be due to individual issues like personal-life distractions, lack of skill or motivation, unexpected illnesses. But that's precisely what the right process is there to help you solve. By and large, your organization shouldn't fall apart when one person has a car accident and is laid up for a month, or limp along when someone isn't up to snuff on a particular set of tasks. So when you're having issues delivering products, see if the problem really is coming from night owl Jill Programmer or eccentric Mike Designer, or if your process is what needs a kick in the pants.

This is where being pragmatic, not dogmatic, in your process decisions can serve your needs better. Your processes are not your customers, your stockholders, your investors, your spouses--the process is beholden to you, not you to it. So if a process doesn't feel right, do spend some time tweaking it, but don't be afraid to shove it aside and try something else.

Now, changing direction too often with your process can send destructive signals: you don't know what you're doing; your team is dysfunctional and can't work effectively (and the team leaders don't know how to address that); the product is too undefined and can't be built. But remember the clothes aren't wearing you. Your allegiance is to your product and customers first, your people second, and the process dead last.

A Heuristic

Once you've used a process with great success, it's possible, even tempting, to settle on it and use it for everything, and that might be good enough. But not every problem is a nail to be addressed by your big hammer, so here's a possible heuristic to decide what approach might work best. Note this isn't a decision tree or a set of solutions; it's a set of simple questions the answers to which can be much more illuminating than you might think at first glance.

Who is going to use the product you're building?
If you're building a fun consumer product, with lots of new features and changes that make your consumers happy, you might want to try quick iterations with soft launches or restricted-availability features that get you feedback quickly so you can tweak and release something new the next week. SCRUM or other agile processes can be very helpful so you don't lose momentum; a drawn-out design and product feature planning process might not be best, because you can't tell on day 1 what people will tell you about your product on day 8, and the 10 features you design up-front might turn out to be unwanted.

On the other hand, if you're building a Web service API consumed by machines, rather than people, you might be better served to spend more time planning up front before you start coding: you might need solid capacity planning, performance testing, redundancy and failover, and because there can be hardware procurement and setup issues, it might be good to know more ahead of time, and then fan out and work on various pieces in parallel.

How much change can be expected in the feature set or interface?
Do you need a rock-solid API and protocols that will last for years and need to be backward-compatible for the next 5 version numbers? Which API calls should you support now to remain relevant in the future (maybe your service is brand new, but a treasure trove of data will emerge from a few months' worth of usage logs). You might want to do some heavy-duty feature analysis to make sure you're not including useless API calls nobody wants, or missing important calls people will need. This doesn't preclude short iterations and frequent milestones, and even fast feature changes, internal to your team: the shape of your end product doesn't have to match your product development practices.

How big is the team working on the project?
Can it be done in a month by a couple of developers and a part-time designer? Is it phase one of a company-defining, all-hands-on-deck product spread over a two-year plan? Constant verbal contact between the designer and developer working next to each other might be a great substitute for a thick PDF spec that fell out of sync two days before the PM last emailed it around; it could be a mess leaving giant holes in the product and SQL injection vulnerabilities all over the place. It greatly depends on...

Who is working on the project?
Software doesn't build itself. The team working on your project is the strongest predictor of success or failure, much more so than the technology they use. So be sure to gauge your engineers, designers, product managers and other actors, and keep your finger on the team's pulse: do they prefer a strongly-defined upfront spec? Do they resent being told what to do? Does Fred Programmer perform best with frequent status catchups, while Sung Designer thrives in a don't-call-me-I'll-call-you rhythm? Do Sung and Fred want to kill each other on a good day, and eat each other's babies on a bad day? More importantly, do you or the team lead actually know all this?

Note this is not a deep insight. In fact it's not an insight at all: different people have different needs, and the same process doesn't magically fit every team. Get a sense of what makes people thrive, or tick, and pick the practices that favor the former and minimize the latter.

Whatever Works

Ultimately your customer will determine whether your project is successful, mediocre, or a failure. Your process can only facilitate or hinder your progress towards one of those end points. It might be a beautiful work of by-the-book SCRUM, or a hotchpotch of Agile / XP on the tech side with an independent design and product team checking in occasionally, or a Soviet-era waterfall. The best process is the one that works for your project and your people, not the one that follows the bullet points in your expensive management consultancy's white paper.


1. True story.