Statement of Values 90
My name is Ben Rady, and I am a software craftsman.
As a technical leader, I value:
- Talented People
- Rapid Feedback
- Individual Relationships
- Facilitation over command and control
- Continuous Improvement
- Frequent Delivery
As a programmer, I value:
- Working Software
- Clean Code
- Rich Communication
- Flexibility over efficiency
- Sustainable Pace
- Simplicity
- Failing Fast over hiding errors
As a human being, I value:
- Courage, not cowardice
- Humility, not hubris
- Compassion, not callousness
- Curiosity, not apathy
- Discipline, not carelessness
- Honesty, not deceit
- Patience, not intolerance
Continuous Testing Explained 140
What is continuous testing? It’s turning the knob on Test Driven Development up to 11, by automatically running the tests on every save. This has profound effects on the way that TDD is applied, and is likely to make you a more efficient and productive programmer.
First, a little history…
The term “Continuous Testing” was originally coined by the Program Analysis Group at MIT. Their research found, among other things, that “Developers using continuous testing were three times more likely to complete the [assigned] task before the deadline than those without” and that “continuous testing reduced wasted time [related to testing] by 92–98%.” These benefits come from a number of interesting effects:
Less Overhead
The first and most obvious effect of continuous testing is that you don’t have to manually run the tests. One less button to push…that’s always a good thing.Defect Lag Reduced
Just as modern Java IDEs like IntelliJ and Eclipse increase feedback and productivity though continuous compilation, continuous testing reduces the time between the introduction of an error and it’s detection. This leads to more effective regression testing, because it’s not the expected failures that cost you time, it’s the unexpected ones. Continuous testing finds unexpected failures right away.Promotes Good TDD Habits
If you’re running the tests on every save, it makes it more difficult to wander off the TDD path. Even though many of the participants in the MIT study were not versed in TDD, several of them reported that they “got a small part of [their] code working before moving on to the next section, rather than trying to debug everything at the end.†Another remarked, “It was easier to see my errors when they were only with one method at a time.†Making incremental changes is a core Agile principle, and directly reflected in the practice of TDD. Continuous testing makes the benefits of incremental development immediately apparent.Tests Stay Fast
Using continuous testing helps keep your tests fast. This is something that was not mentioned in the MIT study, but I can attest to it in my own work. If you write a slow test, you’ll know right away, and you’ll probably have a good idea exactly what is making the test slow (because you just added it). I think the reason that they didn’t mention it in the MIT study is that they weren’t working with legacy code, or external systems, which is where a lot of test slowness comes from.Today, there are a number of tools that support continuous testing:
- CT-Eclipse (was Continuous Testing Plugin for Eclipse) – Java/Eclipse
- ZenTest::Autotest – Ruby
- Fireworks – Java/IntelliJ
- Infinitest – Java
For full disclosure, I should mention that I’m the admin of the Infinitest project. Our goal is to create a continuous test runner for every development platform. We’ve already released a Java test runner, and we’re nearing completion of a Python runner.
Continuous testing is a practice that I have followed in my own work for most of 2007. There is little doubt in my mind that it is the future of TDD. Looking forward to the days of multicore systems, continuous testing may be an effective way to realize productivity improvements through better hardware. So long as they are independent (as they should be), test runs can easily be distributed across multiple cores, and perhaps even, multiple machines.
Hate is good 82
Great people make great software. So what makes great people? Who knows…certainly not I. But I do know some traits that good software developers all seem to share. One of them is a healthy disdain for mediocrity.
Good developers cannot stand sloppiness (in software, anyway). Apathy, haste, and carelessness send shivers down their spines. They may disagree on the best way to do things, but they all agree that things should be done the best way. And they’re constantly looking and learning to find exactly what the best way is. They realize that seeking it is an ever-changing, lifelong quest.
Part of this is a recognition that the best way is the fastest way. Part of it is simply pride in one’s work. I also think part of it may be due to the discreet nature of software…either it works or it doesn’t. The line between success and failure is only one bit wide, and good developers learn through experience that there’s no room for maybe, sort-of, and kinda.
Whatever the reason for it, I see this trait often in the best developers, and not just with code. Slow builds, lackluster testing, and poor communication are met with intolerance and contempt, quickly followed by an intense desire to set things right.
Of course, it’s possible to take this too far. Simply throwing everything out and starting over is rarely the best option. While good developers can’t stand bad code, great developers make cleaning it up appear effortless. The code just gets a little better every day. Every change is a new opportunity for improvement, and every improvement is done in the context of delivering something useful. If you treat your software like boy scouts treat campgrounds, you’ll never work with ugly code for long.
If you already have this disdain, foster it. Critique code (especially your own), and improve it. Discuss it with your coworkers. Read books, articles, and blogs. Most importantly, realize that any code you change is never “done”. If it was done, you wouldn’t be changing it, now would you? Take the opportunity to make things better now. Right now. Otherwise, you’ll lay crap on top of crap and things will be even worse tomorrow.
Peter Gibbons, the downtrodden programmer from the movie Office Space, said “Ever since I started working, every single day of my life has been worse than the day before it. So that means that every single day that you see me, that’s on the worst day of my life.” If you don’t want to follow Peter down the road to code hell, you have to start making things better today. You have to start hating bad code, at least, hating it enough to want to clean it up.
Secure Email with GnuPG 118
So you need to send someone the root password to your webserver? You should just put it in an email and send it to them, right? Well, actually, no…that’s a profoundly bad idea. Here’s how you can use GPG to securely send passwords (and other sensitive information) though email.
Public key encryption allows people to send secure messages to each other without exchanging pre-determined passwords. GnuPG is an open source implementation of a public key encryption system called OpenPGP. Other public key systems exist, but GnuPGP is both free and Free, so that’s what we’ll be using for this example.
First, you get to install GnuPG. If your operating system has a package manager such as apt or MacPorts, it’s generally as simple as:
sudo port install gpg
Creating a Key Pair
Now that we have it installed, lets generate a key pair. Key pairs allow others to encrypt messages to us using our public key, which we can then decrypt using our private key. Doing this in gpg is simple, just type:
gpg --gen-key
GnuPG will then ask a set of questions, including a passphrase, name, and email address. The default values it uses for the key settings are generally acceptable. GnuPG will then generate a key and add it to our keyring, which holds all our known public and private keys. To see the contents of the keyring, we type:
>gpg --list-keys
pub 1024D/A4D1213F 2007-08-23
uid Ben Rady <brady@objectmentor.com>
sub ...
GnuPG then spits out the public and private key ID’s. Now that we have a key pair, we can decrypt messages sent to us. But how will anyone get our public key to encrypt messages? Well, we could export our public key and post it on our website. Or we could just email it to everyone we know. However, there are also numerous key servers around the Internet that host public keys, such as the MIT key server, and we can post our key to one of them. To do so, we type:
gpg --keyserver pgp.mit.edu --send-keys A4D1213F
Sending Encrypted Messages
So once the receipent has generated a key pair and made their public key available, we can send them a secure message. First, we need to import their public key into our keyring:
gpg --keyserver pgp.mit.edu --recv-keys A4D1213F
If you don’t know the key ID that you want to import, the MIT keyserver has a search function that will search by name or email address. However, it’s important to verify that the key you find in the search is really the public key of your intended recipient. Once we do that we (generally) should mark the key as trusted by typing:
gpg --edit-key brady@objectmentor.com
Command> trust
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? 5
Now, we can create a message and encrypt it:
echo 'Secure Message' | gpg -e -r brady@objectmentor.com > secure.gpg
We could have just as easily encrypted one or more files by passing them as parameters to GnuPG. We also could have included multiple recipients. Now we can safely email our secure message (stored in the secure.gpg file) to the recipient.
Receiving Encrypted Messages
When someone sends us an encrypted message, decrypting it is easy.
> gpg -d secure.gpg
gpg: encrypted with ...
"Ben Rady <brady@objectmentor.com>"
Secure Message
And there’s our secure message. Kept safe from the prying eyes of the Internet.
Easy Pairing With Synergy 114
Pair programming is a very powerful development practice. It’s a great way to learn, to solve hard problems, and to write really excellent code. However, there are a number of human issues that can make pairing more difficult than it needs to be. Synergy is a tool that has helped me solve many of those problems. Here’s how…
Synergy is basically a software KVM (without the V). It lets you share one keyboard and mouse among many different computers. While originally designed as a tool for sysadmins, I’ve been using it to make pairing easier, especially in environments that aren’t really conducive to pushing a keyboard back and forth.
Synergy can be run in server or client mode. The machine running the server shares it’s keyboard and mouse with the client(s). I usually run as the server, because I’m pairing with a developer who’s working on some code that he has checked out on his machine. I start the server like this:
synergys --name BensMac
I’m not specifying a config file here, because I have a .synergy.conf file in my home directory that looks like this:
section: screens
BensMac:
WindowsBoxToTheLeft:
super = alt
alt = ctrl
WindowsBoxToTheRight:
super = alt
alt = ctrl
end
section: links
BensMac:
left = WindowsBoxToTheLeft
right = WindowsBoxToTheRight
WindowsBoxToTheLeft:
right = BensMac
WindowsBoxToTheRight:
left = BensMac
end
Synergy treats each machine as a “screen” and the screens are configured here. I’ve got one screen called “BensMac”, which is me. When I launched the server, notice that I specified what screen I was using the --name
option.
I’m pairing with a developer who’s running windows and sitting to the left of me, so he runs the synergy client and connects to my machine like so:
synergyc --name WindowsBoxToTheLeft my.ip.addr.ess
What this does is tell synergy to connect to my machine using the screen name WindowsBoxToTheLeft. As you can see in my config file, that screen is set up with some specific settings. BensMac is specified to be to the right of WindowsBoxToTheLeft and vice-versa. I’ve also remapped a few keys for that screen, so that the command key maps to control and the option key maps to alt (normally, synergy reverses them). I haven’t had the opportunity to set up a LinuxBoxToTheLeft, but the setup would be similar.
Now that we’re connected, I can move my mouse over to the left side of my screen and it “appears” on the other developer’s screen. I can control it, click on things, type whatever I want. I can even copy text on my machine and paste it onto his. I find this much more effective than the standard pairing setup of two developers and one keyboard, because it allows for more fluid collaboration, and makes it much easier to change “drivers”.
For those afraid of the command line, there’s also a windows GUI client that operates in the same way. You specify a screen name, and an ip address, and away you go. It’s any easy download and a great way to start off a pairing session.
If you find yourself pairing a lot, with a lot of different people, try using Synergy. Once you’ve got it configured, it’s quick to set up, and it’s a great tool to facilitate face-to-face collaboration.
Ledger For My Technical Debt 151
All projects accumulate technical debt. It’s just a question of how much and what you do about it. My personal method for tracking debt is very quick, easy, and useful…
Many wiser people than I have espoused that a comment is an apology for ugly code, which is something that I wholeheartedly agree with. So what better way to record your technical debt?
To do this, I take advantage of an oft-underused feature of most IDE’s, the “Task” or “ToDo” list. These tools scan through your source code looking for comments of a particular format, and then generate a list of items based on the comments contained therein. I have three basic comments that I use to record technical debt:
// FIXME
// FIXME With some explaination here
// HACK With some explanation here
The first comment represents short term debt. This is debt that intend to repay (by fixing it) before checking in. I usually use this when I’m in the middle of adding a new feature, and I see and/or create some debt.
The second comment represents long term debt. This is debt that I intent to repay the next time I change this module/class/method. I usually use this when I’m reading through code, without needing to change it, and I see something I think could be improved.
The third comment represents debt I don’t know how to repay. These are usually things like platform bug workarounds, which are sometimes ugly no matter how you write them…you just have to wait for the bug to get fixed.
With this system, I always know how much debt I have for a given project. When looking at the code, the description of the debt is right there, so I have all the information I need to take action without breaking flow. Finally, by keeping the debt record in the code, you reduce the chance that it will get lost or out of sync.
How To Misuse Ant 68
Professional software developers can and should maintain their own build system. We strive to deliver working software, not source code. However, if you want to shirk this responsibility, and you’re a Java programmer, and you use Ant, then there is a way out.
The first step is make your build so complex, brittle, and hard to use that nobody else can even build with it, much less maintain it. Here are some well-worn techniques:
Use Ant Like An Imperative Programming Language
Make heavy use of the if
and unless
attributes, and try to create lots of conditional properties. Chain them together if you can. Try to get it so that it’s impossible to get anything to work without setting at least a dozen different properties from the command line. When you find yourself needing a loop structure, you know you’re on the right track.
Create Useless Default Targets
Useful default targets make it too easy. Make sure you do something that will fail after a clean checkout. And don’t use the standard build.xml filename…otherwise people will be able to build simply by calling ant. Name your build file cibld.v2 or something obscure like that.
Make One Big Target That Does Everything
Just as decoupling and encapsulating your code makes it simpler, decoupling and encapsulating actions in your ant script makes it much easier to read and use…avoid this at all costs. Put everything into one big target that cleans, builds, makes JavaDoc, deploys, runs FindBugs, emails you that it’s done, prints the results to the office printer, and reboots the build machine just for luck.
Don’t Use Metatargets; Use the depends Keyword Instead
A corollary to the OneBigTarget rule is the avoidance of metatargets. By making lots of small targets that do one thing well, you introduce the possibility of chaining them together to do different operations. These “metatargets” allow people to use the build in ways you never anticipated. What horror! Things must be done the way you define them back when you originally wrote the script. Why would anyone have the arrogance to do it another way?
If you have to decouple into small targets, make sure you chain them all together using the depends
keyword. It’s almost as good as the OneBigTarget.
Avoid Self-Documentation
When creating a target, don’t give it a useful or informative name. Be sure not to use the description
annotation for your targets. This can be used with the -projecthelp
option in ant to print out a list of public targets and their uses! How will ever confuse people like that?
Never Refactor Your Scripts
Finally, if you do have to change something (although I can’t imagine why that would ever be necessary), make sure you leave all your old stuff in there. Granted…the source control system is probably tracking all of your changes, but you can never be too sure. It’s best to just leave all those old, crusty targets in there. It’ll confuse everyone else, and it makes it easier for your to find your old stuff without learning how to use subversion.
Once all of this complexity is in place, you’re ready for the big payoff. It was a lot of work up front, but it’s worth it, because now you can argue to your boss that build management is way too hard for you do to all by yourself. Point out that you’ve been spending 30 hours a week on the build and you should have no problem talking him into hiring a build guy to do it for you. Voila! No more build system headaches for you. Just don’t be surprised if, during the next round of layoffs, the build guy keeps his job (how could we manage without him?!?) while yours is shipped off to India.
Of course, if you DO want to maintain your own build system, you can start with a lot worse than my Nifty Thrifty Build Script
Hot Sauce! 13
Good process is like Tabasco; A little goes a long way, and when it’s right, you hardly know it’s there.
I’m a huge Getting Things Done fan. I love quicksilver. Between my hipster PDA, and my many, many text files, I have 1001 ways to record a next action. And yes, that’s 9 ways for you super geeks out there.
Merlin Mann over at 43folders.com is also a huge GTD fan. Merlin made a very good point in one of his recent podcasts that I thought related directly to Agile methods. He was discussing the proclivity of people to spend inordinate amounts of time trying to perfect their system, rather than actually doing the the tasks the system is designed to support. “There is no tonic out there for productivity like actually doing something”, says Merlin. He likens GTD to a coffee cup…the point is the coffee, not the cup. When you’ve got it right, you shouldn’t have to pay any attention to it, you just let it do its job.
I agree with Merlin, and I would apply the same logic to software development. When agile methods are implemented well, somtimes you hardly notice there’s a system at all. You’re in the TDD flow, never being blocked, and rarely being interrupted by meetings. Your day seems to zoom past and at the end of it, as you survey your pile of passing tests, you feel like you actually did something. And you did.
By contast, poorly run projects seem to be almost entirely focused on the process, as though the process was the thing they were selling. Endless creation of documents, and meetings about the documents, and meetings about how to better document the meetings. Every once in a while, almost by accident, somebody gets around to writing some code. Some of it might even be useful to someone, someday.
The ingredients are few and simple, but just as fermenting salt, vinegar and ice cream doesn’t yield a tasty hot sauce, implementing a development process that is nigh-invisible takes more work than you might think. The results, however, are quite tasty.