While the Joel Test is a great way to determine if you have a good team, there are more things you have to do in order to be considered a great developer.
The Joel Test (excerpt from Joel on Software blog):
- Do you use source control?
- Can you make a build in one step?
- Do you make daily builds?
- Do you have a bug database?
- Do you fix bugs before you write new code?
- Do you have an up-to-date schedule?
- Do you have a spec?
- Do programmers have quiet working conditions?
- Do you use the best tools money can buy?
- Do you have testers?
- Do new candidates write code during their interview?
- Do you do hallway usability testing?
Other important things to add to Joel’s list of 12 are:
13. Do you have code reviews before committing or merging to the stable branch?
14. Do you have automated testing?
15. Do you eat your own dog food? (if possible)
In addition to this list of 15 things that identify great teams, I also have my own list that identifies great developers.
I call my list the “Early and Often” list, and they’re the things that software developers and development teams should not only do, but they should do them early in the development process, and they should continue doing them throughout the process.
In no particular order:
- Fix Bugs
Although avoiding the “design by committee” development anti-methodology is imperative, socializing is an important method for bringing other stake-holders along with the rest of the team. By doing this early and often, socializing ideas, product designs, and software designs allows other stake-holders to feel as if they’ve been a part of the process. Socializing product ideas can be tricky if you present an idea and your customers don’t understand it until they see it, but you don’t have to take it quite that far. Allowing users to vote on bug fixes and provide other general feedback on design decisions will help them feel included. The point with your customers (whether in-house or external) is to make them feel like they’re not being left out in the dark, and it’s very important to remember that a multiple-choice survey after the fact IS NOT the same as involving a stakeholder. The same is true for architectural decisions and bringing in other developers that were not part of the decisions. For software designs, you do not have to socialize the design with everyone on the team, but you do need at least one or two others. After all, someone is going to have to review / bless your code.
With distributed version control systems this is a lot easier, but no matter which version control system you’re using you should be committing your code early and often. This helps you keep track of what you’ve done, and sometimes when you’re having a bad day you may just want to go back to a working version. I’ve also found that sharing these commits makes it easier for others to follow along with your progress and understand where you’re going a little more quickly. While this is a little harder to do with distributed version control systems, it’s not impossible. Eclipse and other IDE’s do internal versioning every time you save, which makes this task of committing early and often even easier.
Great software developers manage their source code the way a great sailor manages his boat. Everything has a place, and the place makes sense. New features belong in branches, every release should have a named tag or branch (depending on your version control system). Your main branch must always remain 100% stable, with no exceptions. Branching early will allow you to discard or otherwise shelve code that isn’t ready for production and more readily facilitates iteration and incremental releases.
While a great team has an automated build system, a great developer will use this to his advantage. Even great developers don’t always see or understand the whole solution they’re implementing. The build step will help identify certain problems, allowing the developer to understand more about the solution. This step is more important when developing with statically typed and/or compiled languages, but using static runtime analyzers even with dynamic languages during the build step makes this step an important one.
While the build step can identify issues that occur during compile and static code analysis, the test step can more quickly identify run-time problems. Even if you don’t follow a test driven design or a user acceptance test driven approach, unit tests, regression tests, and usability testing is extremely important. Unit tests and regression tests will help ensure that no matter how much entropy your system has, at least you know when you break something, and if done well testing can prevent many unforeseen side effects.
As part of user acceptance testing, live demonstrations of the software will improve usability, keep performance and stability high on the list of priorities, and keep your users up to date with features that are being developed. If you’re on the right track, this involvement with the users can improve developer/user relationships and keep the users interested and even excited about the product being developed. Using demos as a part of socializing ideas is also an important way of keeping less involved stake holders interested and involved
Great software developers document as they go. The source code provides a lot of this documentation, but any time there’s something that cannot be effectively documented inside the source, a simple little blurb in the README.md or published in a documentation wiki eliminates the risk of losing those all important tidbits of information. Great developers write it while they’re thinking about it because it’s likely they won’t ever think about it again until someone asks. It’s a lot easier to point someone to documentation than trying to explain in an ad-hoc manner.
Committing to shipping early and often forces developers to streamline their shipping process. Whether you’re deploying a mobile app or a website or even a thick client, streamlining your shipping process so that you can re-deploy as often as you wish will allow you to quickly address issues, grievances, that annoying bug that slipped through. It will also provide you with the mechanism to stay ahead of your competition by allowing you to quickly add that nifty new bell or whistle that sets them apart but didn’t really take much effort to code.
9. Fix Bugs
This goes along with Joel’s fifth point, which is to fix bugs before writing new code. Fixing a bug as soon as you see it means that your software is always as bug free as it can possibly be. If you forget some little annoying bug, that’s likely to be the very first thing a user finds… and trust me, they’ll find it. Annoying bugs to you as the developer are critical to end users; your software only gets one chance, and if the “buggy software” bit is ever set by your users then it’s terribly difficult to get that bit reset.
Although it can be argued that failing often shouldn’t be a top priority, failing early is extremely important. Great developers have bad ideas. Everyone does. If time is going to be spent writing code to implement a bad idea, it’s better to find out that the idea is bad sooner rather than later. Great developers will write the bare minimum to get the idea implemented so that the stakeholders can play, touch, feel and determine if the idea is a good one or a failure.