November 09, 2006

Zero Tolerance Manifesto

Based on some conversations at my present job, I decided to write up what I learned during my time at BEA. These are the things it takes to keep a large development team productive. It only really works when these things are built into the culture. You will need tools and infrastructure to make this practical, but if you instill this into your culture, your team will build what you need when you need it.

Just to be clear, the most important thing you do is check in new or improved code into the product. The things below are preconditions to checking in code, the things you do to be a professional developer. If you're doing this right, these things will speed you up, not slow you down. These are not an excuse to decrease your sense of urgency about moving your project forward. Have you checked in code yet?

These are in order of priority:

  1. Don't f'ing break the build. Ever.

  2. If you want to break the build in the privacy of your own machine, that's your business. The second you break the group build, the morale and productivity of every person in the product group dives towards zero. Unacceptable. Here are the steps you *must* take in order to avoid breaking the build.
    1. build your changes before you check them in. Make sure you sync up with product line before you do it -- building against a month old copy of source doesn't really tell you anything.
    2. stick around after you checkin and make sure the group build succeeds. if you broke it, DROP EVERYTHING AND FIX IT. Fix it like your job depends on it. Because it does.
    3. don't check in to a broken build. the second you check in to a broken build, you become part of the problem -- you better start looking for the solution. It sucks to wait, but that's what you should do. Or better, start looking for the person who broke it or his friends and make them fix it. Or better still, figure out what's broken and propose the fix.
  3. Don't break tests

  4. Tests are the teams safety net. Having all the tests passing all the time makes it dirt simple to figure out if you've broken anything with a change. When it's dirt simple to figure that out, you will have more confidence in your ability to make changes safely -- you will write more code and won't shy away from refactoring or taking on changes in new areas.
    1. run the tests for all affected areas and fix any regressions *before* you check in.
    2. check the results of the group tests after you checkin -- assume any failures are yours until you explicitly rule it out. If you broke tests, fix them before you work on anything else.
    3. broken tests are not an excuse to ignore the tests. be sure your change doesn't make the situation worse. if the tests that are broken directly cover the area you are going to be working on, you should probably fix the tests before you make your change. If the product isn't currently at 100% pass rate, then you'll have to baseline the product before you make the product and compare it the results after your change. yes, this sucks, but do it anyway.
  5. write tests. lots of 'em

  6. Tests are your safety net, even for your own code. If you want to be productive, having tests that show something is working gives you a great sanity check on your code, but it also pays dividends over the long haul -- your tests keep you from breaking your own code. Tests are also your shield. If you write a feature and someone later discovers that some part of the feature that didn't have a test is now broken, guess who's going to have to fix it? You. Even if it was someone elses change that broke the feature. The best way to avoid this is to have tests for every aspect of your code that matters. Then it's everyone's responsibility to keep that test passing with every checkin and you don't have to worry about someone else breaking our stuff.
    1. write unit tests for the public methods on all your classes.
    2. write functional tests to verify that the key requirements of your feature are working.
    3. write functional test to verify that your dependencies on other parts of the product are still being satisfied. think of this as writing diagnostics -- when these tests break, you should know where to look to solve the problem.
    4. when something turns up broken without a test, write one. don't let the same regression happen twice.
  7. During parallel development, integrate changes early and often

  8. It is inevitable that at some point you will have to work in two branches of the code at once, usually because one release is ramping down while another is ramping up. When this happens, it's important not to let the backlog of differences between the two versions build up. The sooner you integrate a change forward, the more likely it is to work and the more likely you are to remember what you changed and why.
    1. When you fix a bug or finish a feature in version X, integrate it forward to version x+1 immediately (apply rules 1-3 to integrations too). No sense waiting, it's only going to get harder.
  9. Fix bugs right away.

  10. It inevitable that bugs will sneak through even the most exhaustive testing suite. The unfortunate part of this is that these bugs always come up after you've moved on to something else. This is not an excuse to tolerate bugs, however. If you put off fixing the bug until "someday", chances are you won't fix it or that it will take you a lot longer to fix then than if you just fixed it today.
    1. When a bug comes in, fix it. Whatever you're working on, come to a natural stopping point, then set it aside and fix your bug. If a bug turns out to be too large to be accomodated in the slack of your current sprint, put it on the backlog -- and do it first thing next sprint.
    2. Leave slack in your sprint commitments to accomodate bug fixing.
    3. Don't defer bugs indefinitely. If a bug isn't important enough to fix now, then you should consider closing the bug. This is especially true for large bugs or minor enhancements of marginal value. Keeping it around is a drain on your attention and it invites you to keep other bugs with it. Don't be careless, but don't be overly cautious either -- if a bugs important, it'll come back.
    Posted by dapkus at 08:57 PM | Comments (0) | TrackBack