A Folder Full of Middles

Once again, it’s been a while since I’ve published here. But that’s not to say that I’m not writing. I really am. I feel like I have tons of great ideas, and I’m working through many of them.

In fact, here are how many ideas I’m working on right now:

marvin:writing srbaker$ find . |wc -l
      76

I keep hitting a block. I get my good idea out, but I can’t build up to it, or conclude. It’s frustrating. When I was complaining to a friend about this, she said it reminded her of a Kids in the Hall sketch. I’ve embedded it here so you can enjoy it while I work on sandwiching some of my middles.

I’ve also got some trimming to do.

marvin:writing srbaker$ for i in `find . -type f`; do cat $i; done |wc -w
   27725
Share

Optimizing Stand Up

A quick daily meeting to check the pulse of your project can be immeasurably helpful to everyone on the team. If you’re not careful, these quick daily meetings can easily turn into long sessions where everyone talks, not much is said, and even less is heard. One of the ways to encourage these meetings to be more efficient is to have them standing up.

Even though more and more teams are working remotely, the daily meeting is still often referred to as stand up. I work remotely, and participate in “stand up” every day: I’m just rarely standing. Most mornings I’m still wearing my pyjamas, or even less!

These days “stand up” is something that many teams practice. I’ve been on very few teams over the past decade that didn’t have a stand up every day, and in the few cases where they didn’t I strongly recommended it. Unfortunately, many teams don’t do stand up very well. I hate to see teams not realizing the full potential of the things they do, but I hate even more to see teams doing things that provide them no benefit at all.

I feel the same way about stand up that I do about testing. Doing stand up poorly is worse than not doing stand up at all. I find so much value in daily stand ups, though, that I want to help ensure that teams as many teams as possible are doing it well.

If it Doesn’t Work, Don’t Do It.

First, I want to point out that stand up may not be for everyone. Treating stand up meetings as a prescription is completely foolish. There are some teams that won’t realize any benefit from stand up, and those teams should stop wasting their time.

If your team has infallible communication, an office that buzzes with chatter about the things that are being worked on, or an online chat room that is constantly active and up to date, stand up probably isn’t necessary for you. There’s an easy way to tell if stand up isn’t right for your team: If most people on your team generally know what everyone else is working on, at any given time during a day, you might be wasting your time at stand up.

For the rest of you, keep reading.

Background

Over time, definitions and meanings can get cloudy and confused, so I thought I would go back to the “horse’s mouth” to demonstrate where we’ve come from. To find out the origins of stand up, look no further than Stand Up Meeting on the C2 wiki.

You want everyone to know what’s going on, even if they weren’t there when something interesting happened. You want to know who’s got a problem you can help with, you want to get help if you need it. You need a forum to announce interesting upcoming events.

Ron Jeffries goes further and describes exactly how his team on the C3 project runs a standup.

Every day at a specified time (C3′s is 10 AM), everyone on the team (developers, customers, people passing by) stands up in a circle. Go around the circle and briefly describe what you’re working on, how it’s going, anything interesting you have discovered, any problems you are having.

Stand up came from simple roots. Go around the circle and say what you’re working on. Don’t account for hours; don’t re-iterate conversations that everyone was involved in. Simply state what you’re working on.

There are some great links on the C2 page, including some stand up anti-patterns. As always, C2 is a wealth of knowledge, and I expect you to click on anything interesting and read it. See you next month.

Punching the Clock

The most common stand up format I’ve experienced is “This is what I did yesterday, and this is what I’ll do today.” Sometimes a request for help will get thrown in, but not often. This is the format that I’ve experienced on nearly every team I’ve been involved with over the past several years. In fact, every single project I’ve worked on that has had remote members used this format.

Chances are this is the format your team uses. It is the 21st century equivalent of punching the clock. It’s adored by the bean counters and the micro-managers, but it’s not useful at all to your team. To your team, the people who work with you, what you did yesterday is almost universally useless. Why? Because you told them yesterday what you were working on then. As your teammate, I want to know what you’re working on right now, so I can infer which ways we might be able to help each other.

The worst part about this format is that it causes people, especially remote folks, to be defensive about how their days are spent. Long lists of mundane and trivial tasks are read. Sometimes you’ll hear things like “I didn’t get much done because I was in meetings all day yesterday.” That information does not do your team any good, and it’s demoralizing to have to say “I didn’t get any work done yesterday” even though sometimes it happens.

Work in Progress

Another format that I’ve encountered is to iterate over “work in progress”. That is, we opened Pivotal Tracker and talked about each of the open stories. The person currently assigned to that story explained the status and anything relevant that the team might want to hear.

This worked out rather well. It meant we were talking about what we were working on right now. We weren’t uselessly accounting for hours, and we weren’t talking about things our teammates didn’t care about like how many meetings we had yesterday.

It wasn’t perfect, though. We spent time talking about long-running or stories which probably didn’t need to be discussed, because we were iterating over every story. We often missed opportunities to talk about things we learned or other important bits that weren’t tied to a specific story. This format also gets cumbersome when you have a large number of stories in progress due to a slow QA process, or organizational blockers.

Optional Stand Up

Format isn’t the only problem with stand up today, but a poorly executed stand up will lead to other problems. If your team is punching the clock and trying to make it sound like they were busy yesterday, the rest of the team is going to tune out. If members aren’t getting value from stand up, they won’t feel that it’s important to be there. This is both a symptom of other problems, and a problem of its own.

Recently, I participated in a stand up in which a co-worker attended remotely while in bed sick. When I announced what I was working on, my sick teammate offered to email me some relevant documentation before tending to his ailments. On a day that would have been otherwise lost to illness, my co-worker was able to save me a considerable amount of time effectively making up for what would have otherwise been a lost day.

If you find that members of your team routinely miss stand up, or often have conflicting appointments or engagements, your stand up probably needs to be improved. Mandating that stand up is required isn’t an effective way to solve this problem. Simply making sure that stand up is valuable to everyone on your team will encourage them to join.

Proper Tools

Stand up is easy when everyone’s in the same office. Simply stand in a circle, and everyone speaks after the person next to them. If your team is partly co-located, it’s a bit harder to do well. Do everyone on your team a favour and buy a proper conference phone. It’s really hard to be engaged in stand up when you can’t hear your teammates, or they can’t hear you. It’s also hard to know which order to go in, without visual cues, so it’s important for someone to take the lead and call names for each turn.

If your team is remote, you’ll need some tools to help out. Skype is a simple choice if your entire team is remote. It lacks visual cues, so you’ll still have to appoint someone to keep order. There are free phone conference services, if you want to be able to call in from a telephone. There aren’t many video conferencing solutions that can support an entire team, but I’ve had good luck with Adobe Connect.

If your team is all located in one office, I would still recommend having a conference line available for days when people can’t be in the office. This enables people to contribute even when they can’t be in the office.

How to Stand Up

I’ve been over a lot of the issues that many folks have with getting the most value out of stand up, so I’d like to close by suggesting how to get the most from your daily meeting.

As with most things, the best thing you can do with stand up is to keep it simple. Don’t spend time on bits that aren’t useful to the other members on your team. If you need help, ask for it. If you learned something that might help others, share it. And if you can provide specific help to someone else, offer it. Your status should be present tense.

Just answer this question: “What am I working on right now?”

Share

Identifying Quality Problems

I learned the importance of software quality when I wrote my first computer program. In the many years since that experience, I’ve focused on learning the methods and techniques for developing the best possible software. On occasion, I’ve been known to write some tools to help developers produce high quality software.

Much of my recent career has been spent helping teams overcome poor quality. I’ve been surprised by just how far in denial many teams are about the quality of their software. In a few cases, the team understands that they might have some quality issues, but don’t know how to identify them or what to do to improve quality. In many cases, though, the team fails to acknowledge that they have quality issues even when the evidence is overwhelming.

Whether you’re the developer committing the offense, or the hapless victim paying for it, it’s possible that you’re not aware that your software has quality issues. I’ve identified a few common symptoms of poor quality. These will hopefully help you understand whether you have quality issues or not. My guess is that for most teams, at least some of these symptoms will be familiar.

  • Has development slowed noticeably? Does it take longer to add new features now than it did in earlier days of the project?

  • When you add a new feature, do bugs appear in unrelated code? Does touching one bit over here cause things to break there?

  • Are there dark corners in the code base which developers go to lengths to avoid touching? Are there bits of code that are touched by one person, and only when he or she absolutely must?

  • Do you often release series of patches immediately after deployments? Do you have to babysit them? Is your team afraid to deploy at certain times?

  • Is it difficult to remove obsolete code, or replace existing features with new and improved ones?

These are all very common problems. So common, in fact, that many just assume they’re part of the cost of doing business. They are not the cost of doing business. They are the cost of doing poorly. If you find that any of the statements above are true for your project, it is very likely that you have software quality issues.

Poor quality in software hurts the current team, and all future members that have to work on the code base. No developer wants to make their own job harder, and they are not likely to want to make difficult work for the developers who work on the software in the future.

I’m going to use this space to examine each of the symptoms outlined above, the specific causes of each symptom, and provide some tips on how to fix those. Keep watching here, or on my twitter feed for an exploration of why the development of your project has slowed.

Share

The Hockey Trivia Game

My first computer program was a hockey trivia game. It would ask you a question like “Who is the best goaltender in the NHL?” and you had to type in “Patrick Roy” with perfect capitalization and spelling to be get a point for answering correctly. My program would then ask 19 more of these kinds of questions, and at the end report how many were answered correctly.

At first it asked the same twenty questions, in the same order, every time the program was run. There weren’t many bells and whistles in those days: no scoreboard, no persistence, and no preferences to change the colour scheme (which was red on blue, because I have an eye for design). Adding a new question was done by simply copying and pasting the code for the previous question and modifying the contents. (A method that many others still use today, unfortunately.)

I was quite proud of myself, and very happy with my first computer program. My teachers and family members were impressed that not only could I use the computer at all, but I could write programs to tell it what to do. Many hockey trivia games were played in my house, and in my classroom.

Someone asked why the questions were always the same, and someone else wondered why they were always presented in the same order. So I learned about subroutines and randomization, and added those features. Later, someone wanted to add new questions and answers to my program, so I had to learn about reading and writing files.

Before too long, I wanted to add a “party mode” to my game, so I had to add multi-player support, and keep track of which questions were answered incorrectly so I could provide the correct answers. These changes were daunting: it would have been easier to re-write my program from scratch and building those features in from the start than it would be to change my current program to add the features I desired. My program had become an unmaintainable mess, and I didn’t know how to solve it.

Of course, I did what many software developers do. I planned a Big Rewrite. This time, I’d use better tools because QBASIC had failed me so desperately: Turbo Pascal was a good tool, and a *real* programming language. My new program was easy to plan, because the feature list was simple: everything the old program did, and then some.

The rest of that rewrite story might actually be interesting, but this isn’t about big rewrites, so I’ll jump ahead to the spoiler: the re-write failed, and so did the one after that. Eventually I wound up doing what developers on most failed big re-writes do: I went back and hacked in multi-user support (that didn’t really work) on to the original QBASIC version.

I know now that the problem wasn’t the tools. There are better tools out there, sure, but QBASIC was certainly up to the task of my simple trivia game. I also now know that the problem wasn’t that I didn’t do enough up-front planning to fit the features I wanted into my software. The problem was simply that I didn’t know how to develop a software system that would respond to change.

A lot of time has passed since that failed rewrite. Three things were true then that aren’t true now: the New Kids on the Block couldn’t legally drink alcohol together in the United States, Steve Urkel wasn’t old enough to drive an Isetta, and I didn’t know how to write maintainable software.

My hockey trivia program ended up being unmaintainable. Adding new features was so painful and error-prone, that I didn’t really enjoy working on it anymore. Finding and fixing bugs took forever. I couldn’t even re-use the code that I had written in new programs, because it was bound so tightly to the concept of trivia questions about hockey. My hockey trivia program was a failure as a software project.

I knew that my software project had failed, and I knew it was my fault. My project failed because the software I had written was of such a low quality. Not only had I let myself down, but I had let down potentially millions of people who might have wanted to test their hockey trivia knowledge!

Share

Isolating Rails 3

I’ve written here before about my love affair with Isolate. Isolate is a beautifully simple tool for installing RubyGems in a sandbox. I really enjoy not having to think about conflicting installed versions of gems, or infecting my system with gems that I won’t ever use. I use it on every single project I touch, whether it’s used upstream or not, and it rarely takes longer than a few minutes to move an existing project to it. It’s even possible to use Isolate to wrap other RubyGems sandboxes, such as Bundler, in its warm embrace.

A RubyGems install on any one of my machines looks like this:

srbaker@gobo:~$ sudo gem list

*** LOCAL GEMS ***

isolate (3.0.0)

Setting up a Rails 3 project skeleton requires the rails gem to be installed, and then requires you to invoke an executable included in that gem. The solution for bootstrapping a Rails 3 project without installing the gem system-wide is not immediately obvious to many people, so I’ve decided to document the process here. Isolate has a terrific feature that allows you to invoke shell commands inside the isolated environment by using a rake task, you just need to get Rails installed in that environment.

To start, I create a new directory for my Rails project. In the new directory I create my Isolate file, which has one line:

gem 'rails', '3.0.3'

Next we need a rakefile which will load Isolate and sandbox the Rails 3 gems. I call this file ‘bootstrap’, since Rails will generate a Rakefile. The ‘bootstrap’ rakefile looks like this:

require 'rubygems'
require 'isolate/now'
require 'isolate/rake'

If you have the Rails 3 gems install, a new project is created by using the ‘rails new’ command. Since we have a bootstrap rakefile created which will sandbox Rails 3, we can create the Rails sandbox, and our new project with the following command:

$ rake -f bootstrap isolate:sh['rails new . --skip-gemfile']

When this command has run, Isolate will install Rails 3 and its dependencies, and then run the command ‘rails new . –skip-gemfile’. You will have a new Rails 3 project in your current directory. The next thing you should do is add a reference to the gem(s) that support your chosen database engine. I usually run sqlite3 locally, so I add gem ‘sqlite3-ruby’ to my Isolate file. You may also want to use ‘pg’. (You might be forced to use ‘mysql’, but you should never do this by conscious decision.)

Since Rails depends on Bundler out of the box, we need to get rid of this dependency before continuing. It will still continue to be installed in the sandbox, since there is a gem dependency on it, but we don’t want our application using it. To do this, edit config/boot.rb and remove all of the lines that load Bundler; on Rails 3.0.3, remove the following lines:

# Set up gems listed in the Gemfile.
gemfile = File.expand_path('../../Gemfile', __FILE__)
begin
  ENV['BUNDLE_GEMFILE'] = gemfile
  require 'bundler'
  Bundler.setup
rescue Bundler::GemNotFound => e
  STDERR.puts e.message
  STDERR.puts "Try running `bundle install`."
  exit!
end if File.exist?(gemfile)

Load Isolate instead, by replacing those lines with these:

require 'isolate/now'
require 'isolate/rake'

(You may want to put the isolate/rake requirement in your Rakefile.) You should also remove the call to Bundler.require in config/application.rb as well.

For more information on Isolate, please read my introduction “Introducing Isolate“, and also visit the project on GitHub.

Share

Introducing Isolate

Isolate is a tool for managing RubyGems by including them within the project that requires them. At Goldstar, we recently switched from Bundler to Isolate for managing our gem dependencies. (I wrote about that experience here.) We have found Isolate to be stable, beautifully simple, and easy to extend. Most importantly, new developments and feature enhancements have been welcomed with open arms.
webb

Getting Started

Of course, you’ll need to install the Isolate gem to get started. The usual gem install isolate will do the trick just fine. Once you have Isolate installed, you must initialize it in your project. In a Rails project, config/preinitializer.rb is a great place for this initialization code. In non-Rails projects, put the following in the file that’s loaded first, or a file that’s loaded before any gems are required.

require 'rubygems'
require 'isolate/now'

That’s all that’s required for Isolate to be initialized. Isolate will now look for a file called Isolate in the current working directory. The Isolate file contains lines that describe which gems are to be installed for your application. Here’s a sample Isolate file that specifies some gem dependencies:

gem 'chronic'

When Isolate runs (in the app’s initialization), it will install the latest version the chronic gem in your application.

Specifying Specific Revisions

Depending on a moving target is tricky business, as a new version of chronic could be released which breaks compatibility with your app. You can specify which version of a gem to install as the second argument to the gem method.

gem 'chronic', '0.2.3'

This will make sure that only version 0.2.3 of the chronic gem is installed. If a new version of chronic is installed, you don’t have to worry about updating your project to support it until you’re ready.

Build Arguments

Some gems will require build arguments to be passed in order for the extension to be built properly. Using version 2.7 of the mysql gem may require build arguments to be passed in. Build arguments are passed via the :args keyword argument to the gem method. Like so:

gem 'mysql', '2.7', :args => '--with-mysql-config=/opt/local/bin/mysql_config5'

Of course, putting this in your Isolate file and checking it in is going to be problematic if different members of the team need environment specific build options. To solve this problem, Isolate will look for a file called Isolate.local which can override any of the settings in Isolate. It’s up to your team to decide on a best practice for what settings to put in the global Isolate configuration, but each developer can override those settings in Isolate.local.

Automatic Requires

A last point I want to make, for those of you migrating from config.gems or Bundler, is how to solve the auto require problem. Rails’ config.gems and Bundler both have a stupid bug which automatically requires the gem name upon installation. You may find that your code depends on this idiotic behaviour when you move to Isolate from one of these projects. You can simply add the following code to the bottom of your Isolate initialization to auto-require as gems are installed.

# FIXME: autorequire is stupid
Isolate.instance.entries.each do |e|

  next unless e.matches? Isolate.env
  begin
    require e.options[:require] || e.name

  rescue LoadError => e # eat the LoadError
    end  end

Using require ‘gem-name’ is the expected behaviour for most gems. For gems whose library is named differently from the gem, you can specify the library name to require with the :require argument to gem. For ‘mime-types’, you can use:

gem 'mime-types', '1.15', :require => 'mime/types'

If you’re not inheriting code that depends on this behaviour, please do the rest of your community a favour by not propagating it, and place your requires properly where they’re needed.

What Next?

I’ve said many times that the feature I love most about Isolate is how simple it is. The entire code base is less than 800 lines of Ruby, with about half of that number being taken up by tests. As you saw in the Auto Require example, extending Isolate is painless, and the Isolate developers (a group which I am happy to be a member of) are happy to hear feedback and integrate patches. If you run into problems using Isolate on your project, please drop by #isolate on Freenode and we’ll be more than happy to help you along.

Share

From Bundler to Open and Inclusive Software Communities

Last Friday marked our first production deployment at Goldstar using Isolate to manage our gem dependencies. We are very happy about this move, because it is a beautifully simple tool that has saved us a lot of pain. My co-worker BJ Clark wrote about the pain, and received a lot of undeserved flack. This is the background to what BJ wrote.

I’m going to follow this post with an article about the differences between Bundler and Isolate, as well as how to start using Isolate in your own Rails project. Before I do this, though, I want to describe the events that led us up to the switch, because I think it’s representative of a huge problem in the Rails community. Though we ended up switching to what I consider to be a technically superior product based on simplicity, we arrived there because of poor community interaction on the part of the Bundler developers.

I want to reiterate that, because it’s the thesis of this article, if there is one: Despite some technical issues with Bundler, we moved away from it because of the Bundler team’s refusal to play nicely. This isn’t an isolated incident, either. In the 7 years or so I’ve spent developing in Ruby, I’ve certainly encountered technical issues and poor code, but all of the technical issues and poor code I’ve encountered do not disappoint me as much as the mountains of political bullshit that I’ve had to endure.

I’m going to cut the technical details out, because they’re just the symptoms, but it’s worth summarizing: we ran into a bug where Bundler would refuse to upgrade a bundled gem. When we tried to upgrade to Bundler 0.9, which fixed this bug, we found that an important feature was removed. After reading the source code to confirm that the feature was indeed missing, I hopped on to an IRC channel where I could find the Bundler developers to get some assistance. The conversation went like this:

Me: How do I specify build options with Bundler 0.9? I can’t seem to find documentation, and I can’t find in the source code where it’s used.

Developer: It was removed.

Me: What replaces it?

Developer: Nothing yet, but some day we’ll make it way better! Stay tuned!

Me: Will this be in the next release? Our business depends on it.

Developer: Maybe. It will be in a later release, and it will be way better.

Me: How can I work around this missing feature in the meantime?

Developer: You can do this.

Me: That doesn’t work for me.

Developer: Okay, you can wait for the later release then. It will be way better!

I went back and talked to my co-workers. We were stuck: our business depended on Bundler, but the version we had contained bugs that made it difficult to use. The new version was missing an important feature, which made it impossible to use.

I decided to give the Bundler developers the benefit of the doubt. At the time, I was sure they had good reasons for removing the important feature, and I didn’t expect them to stop what they’re doing to add it back just for me. We weren’t the only folks bitten by the removal of this feature, though, so I offered to work on a patch and contribute back.

Of course, I wouldn’t want my work to be conflicting with someone else’s, and I didn’t want the effort to be duplicated. So back to the Bundler Developers I went:

Me: We really need build options. Is anyone currently working on it?

Developer: Nope. But we will be some day, and it will be way better!

Me: Well, we need it, and a bunch of other people do too. How about I save you guys the trouble, and I write the patch myself?

Developer: Okay, you can write your own version until we do it properly.

Me: But if I contribute the feature back, you won’t have to do it because it will already be done. I don’t want to write it if you’re just going to throw it away later. That’s wasted effort.

Developer: You’re not smart enough to do it.

Me: Empirical evidence suggests otherwise.

Developer: There are requirements you don’t know about.

Me: If you tell me these requirements, then I will know about them and I can write an appropriate patch.

Developer: Well, we need to support multiple versions of Ruby. You’re not smart enough to support multiple versions of Ruby.

I left this conversation pretty well pissed off. Here I was offering my time, and my employer’s time, to fix a bug that many people had experienced. In response to my generosity, I was being told that if I spent my time and effort fixing this bug my work would be thrown away. We started out with a technical problem: we found a bug in some software. This led to an offer of collaboration to solve the problem. The offer was refused, not because I wasn’t capable of helping: I’m not exactly new at this. The offer was refused because anything not done in the tight little circle of the Bundler development cabal was not sufficient. It was probably the worst case of NIH I’ve ever witnessed.

I will add that after this conversation, I was able to finally make some headway, and get an agreement that, if I did it in exactly their way, they might just possibly accept a patch from me. I still wasn’t convinced that I could take their word for it, though, so I started looking for alternatives. I decided to give Isolate a shot, which I was aware of because I know the developers that wrote it. In a couple hours, I had our application moved over. In a day, I had all of our deployment and management scripts moved and updated for Isolate.

Isolate was (deliberately) missing one feature, and jbarnette was nice enough to help me solve it with a small patch to our environment. Also, because we have two requirements that weren’t encountered before by Isolate’s authors, I was made a contributor to the project so I can add those features for everyone to enjoy. Isolate wasn’t technically the 100% solution for us, but it was the 99% solution. Better still, I’m not only allowed but encouraged to provide the last 1% myself.

I hope that this situation turns out to be less common in the future than it has been in my experience. We need to have open, and inclusive environments where we respect each other and their needs. Developing software, especially open source software, in silos without outside help and encouragement leads to projects that are fragile that don’t solve the problems they were intended to solve.

Share

Paying Knowledge Forward

The Food Network is the default channel on our TV. I think I enjoy food and cooking for the same reasons I love developing software. In both cases, you’re creating something where before there was nothing. You may be following a recipe, you may be trying something new, but in cooking as in software you’re creating something for other people to enjoy. I think that’s why cooking also appeals to many of my programmer friends.

Tonight I watched part of Jamie Oliver’s Ministry of Food. In it, the Naked Chef has a fantastic idea to improve the way people eat. Jamie travels to an economically depressed town and teaches ten recipes to ten people who have rarely (or in some cases never) cooked for their families. In exchange for Jamie’s knowledge these ten people each promise to teach the recipes and skills to two more people, who must promise to teach two more people, and so on. Jamie’s lofty goal is to create exponential growth in culinary skills for people that can really benefit from those skills.

Jamie’s plan is not a terribly new idea. It was even brought into pop culture in the 2000 film Pay It Forward. Jamie’s name for his project, “Ministry of Food” also isn’t new: it references a government organization created in the UK at the start of World War II to help people make the most of their rationed food.

I find Jamie Oliver inspiring for many reasons, but this particular show was especially inspirational because Jamie is teaching valuable skills to people who would otherwise not had the opportunity to learn them. This is a very close parallel to the part of my own work that I find most rewarding: teaching software development practices and skills to people who wouldn’t have the opportunity or tools available to learn them otherwise1.

Turning to chefs for inspirational ways to improve our craft is hardly a trail I’m blazing. In Thoughts on the Future of the Boutique Software Shop, Michael Feathers uses Gordon Ramsay (another of my favourite chefs) as his inspiration for talking about the paralllels between software development and the culinary world.

I feel that the software industry is a pretty broken down in many places, much like an economically depressed small town, but I don’t think it’s impossible to fix. There are very few, if any, people out there who deliberately write poor quality software. Many developers just haven’t had the opportunity to learn how to write software well. The problems in our industry are due to a lack of education2.

So, in an attempt to improve the software development industry as a whole I’m going to follow Jamie’s culinary lead, and employ the same method. From now on I’m going to make sure that in addition to posting my thoughts here for the world to see, I’m going to specifically reach out to at least two people who can benefit from the things I have learned. I will ask those people to reach out to two people and help them. I want everyone that learns something new to reach out to two people and share what they’ve learned, and ask those people to do the same.

Reaching out to two people personally does not mean blogging or tweeting. We already have that; it’s passive engagement. I want you to actively reach out to two people individually, and personally. Send a personal email, an Instant Message, or make a phone call. Better yet meet for a real chat! That way, we’re all helping each other. We’re improving the craft exponentially. And we’re having important and valuable conversations along the way. I think sharing knowledge can reasonably be considered part of Doing Your Damned Job.

To encourage this process of knowledge sharing, I’m going to start asking: “With how many people have you personally shared this thing you’ve learned?” I would like to encourage everyone else to do the same. I really hope this is something that some people will get behind, because I think it can work.

To get started, go and share an important piece of knowledge with two people. Tell them to share that knowledge with two people. Let’s make life better for everyone that chooses to be a part of this terrific craft.


1. An idea that I struggle with sometimes is that it’s not about opportunity, it’s about aptitude. I used to completely disagree, but I just finished working with someone who has convinced me that there are some people that are entirely beyond help. These people are in the minority, though. Most problems with software quality are due to ignorance, not stupidity.

2. Okay, and ego. But ego problems are just education problems for unwilling students. But let’s pretend everyone is as awesome as I am, and has the same lack of ego.

Share

Test The Hard Stuff

I am pleased to see testing taking a bigger hold in software development circles over the past few years. It is especially pleasing to see that TDD and BDD are really catching on as the best way to ensure that it’s done well. I’ve seen a lot of projects over the past few years, and the number that I see without an attempt at a comprehensive test suite is smaller every year. It warms my heart.

I often get introduced to a project with a very proud exclamation: “Not only do we have tests for everything, they were written first!” I’m sure most of you will understand that there’s not a lot related to testing Ruby that I’m likely to find new and exciting. Sometimes there’s a neat hack, or an interesting idea, but it’s inevitably variations on a theme I’ve been intimately involved with for the past 5 years. It’s not just because of my involvement, though, it’s because testing Ruby is the easy.

I don’t get excited when a team tells me they test drove their Rails application. I expect it. It’s part of Doing Your Damned Job. Testing Rails applications is a solved problem.

I often get excited by their enthusiastic proclamation of testing, though, and I ask hopefully “What are you using to test the JavaScript?”

“Oh, uh, well, you see, uh, we only tested the Ruby parts. Testing JavaScript is hard!”

My heart sinks every time. There’s a simple reason why, and I’m going to embolden it for you, because it’s important. If browsers still had a blink tag, the following would be an appropriate usage:

The stuff that’s hard to test is the stuff that needs it the most.

This isn’t just related to writing JavaScript in a web application. This is a universal truth. A very common reason why things are hard to test is that they’re tightly coupled and have really mucky dependencies1. If something is tightly coupled and has really mucky dependencies, your tests will shine a floodlight on them and provide you with a roadmap for cleaning them up.

When you test the Ruby parts of your Rails project, that’s great. I’m glad you’re making an effort to Do Your Damned Job. But if you rely on JavaScript (or other languages, for that matter) those parts need to be treated with the same care and attention that you paid to the Ruby parts. Testing part of your application is not Doing Your Damned Job.

Part of the problem with testing JavaScript is one of bootstrapping. Getting the testing frameworks set up and running can be combersome. Many of them are poorly documented, lots are incomplete, and some just aren’t that great. Why do you think that is? Because only a small fraction of the people are doing their damned jobs and building comprehensive software all the way down. Pick a framework, use it, and write about your experiences.

Consider a Rails application that has a beautiful test suite for all of the Ruby stuff and none for the JavaScript. You’ve tested the parts that interact with the database, the basic workflow, and the backend of the application. The stuff you left out is the stuff the user sees and interacts with heavily. Because of the tight coupling and dependencies, the stuff you haven’t tested is the most fragile.

Question: Is it most likely to break in front of the user because it’s JavaScript and JavaScript testing is hard, or is it most likely to break because you didn’t test it?

Answer: Your users don’t care.

If testing is part of Doing Your Damned Job (hint: it is) then it certainly includes testing the hard part.

So if you send me a Rails project that has nice comprehensive tests for the Ruby, and a hairy unmaintainable mess of JavaScript, don’t be surprised if I say “Hey, thanks for doing the easy part.”2

Watch this space for some notes from the trenches on testing the hard stuff.


1. This is especially true of JavaScript: it’s tightly coupled to the browser and the DOM, and the dependencies on both are mucky.

2. I probably won’t mutter “fucker” under my breath, but don’t be surprised at that, either.

Share

Do Your Damned Job

I’ve heard the phrase “Developer QA” being thrown about quite a bit lately, and recently encountered it at work. Basically, when people talk about “Developer QA”, they’re referring to a developer ensuring that the code they’re pushing forward is of high enough quality to make it into production. Who could argue with that? Lots of people, it seems.

There is some disagreement about whether “Developer QA” is required, and I think it’s a language issue (read about my good friends Sapir and Whorf). “QA is not the job of the Developer; that’s why we have QA” sounds perfectly reasonable. Why should developers do someone else’s job? When using the phrase “Developer QA” the language suggests that Developers are given tasks from someone else’s job description.

However, I don’t think the suggestion in the language is the intended outcome. Certainly, ensuring that the code works is the developer’s job. (Feel free to disagree, but you’ll sound ridiculous.) So from now on, I’m not going to say, or enjoy hearing, “Developer QA”. I’m going to say “Do Your Damned Job.” I might even type DYDJ for short.

I’m not a big fan of negative reinforcement, but I am in full support of loud and critical commentary for every person that pushes a 500, blatant oversight, or other atrocity to QA. (Myself included; I pride myself on being my own worst critic.) When you do this, you are wasting your co-workers’ time, and that’s just not nice. They’re not going to invite you over for BBQ if you keep being not nice.

Writing tests is one very important way to DYDJ. On a project that has been well tested from start to finish, including a comprehensive suite of acceptance tests, I even feel comfortable pushing to QA without even looking at it in a browser. Few people out there will have code that is tested this well. If you have code that isn’t well tested, it can’t provide you with that level of comfort: You’re going to have to click through.

The bottom line is this: as a developer, it’s your responsibility to make sure your stuff works. That is not QA, my developer friends: That’s doing your damned job.

Share