Improving your development process takes time and effort, but always pays off in code quality and professionalism. When consulting for an organization I always recommend the following 5 steps that I feel are essential to any development process. You may already be using these recommendations in practice as they are all well-known techniques and tools so I certainly applaud anyone who can check off each step. Note that each step requires learning, practice, and discipline, so if you are introducing something new, take it a step at a time. Process improvement doesn’t happen over night.
1. Write tests for your code, then write more tests
I won’t get into the religious battles generally surrounding Test Driven Development (TDD), but regardless of what you believe you should be writing tests for your code. Professional software developers write tests and run the test suite after making logic changes. As Robert C. Martin put it in Clean Code, “Code is never clean unless it has tests.” Enough said.
What it requires:
- A unit testing tool such as JUnit or TestNG. I also recommend a code coverage analysis tool for measuring how well you’re doing with your testing such as Cobertura or Emma.
- Learning to write testable code (e.g. small methods that generally have a single responsibility).
2. Don’t let your code changes become stale, commit regularly
Don’t hang onto your changes locally for an extended period of time. For continous integration to flush out issues early, you must integrate your code with other developers often. If you follow the technique of continuous commits, it will re-enforce itself on other members of your development team over time.
Merging is a pain to say the least. In a continuous commit environment, the longer you hold onto changes, the more likely you will have to merge. Other developers will soon realize that if they do not follow this approach, you are going to make their life miserable.
What it requires:
- Breaking your work into smaller chunks that can be completed in reasonable time periods.
- Developing the habit of committing as you finish a logical chunk of code.
3. Setup a Continuous Integration (CI) server
Continuous integration (CI) is nothing new, but I’m always surprised at how many environments I encounter that are still not using this vital development technique. Setting up a CI server is easier than ever thanks to some outstanding open-source projects.
What it requires:
- A build that is autonomous, i.e. doesn’t rely on external input such as compiling the source files in Eclipse, to achieve the goal of building the project artifact(s).
- A CI server implementation and a build machine to install the server on. Popular implementation choices include Hudson and CruiseControl (the original).
4. Automate scheduled releases to a production environment clone
Aka: Release Early, Release Often. The CI server can deploy releases to a production environment clone based on the current stable code in the VCS. If possible, this deployment should be fully automated and should generally occur at a specific time.
To avoid downtime for user testing it is not recommended that this occur on each commit. As the size of the team grows this can become quite a hindrance with continuous commits. Deploying a release somewhere between nightly and weekly at a time when usage is low is generally reasonable.
What it requires:
- A way to deploy the application from the CI server to the production environment clone. With the hot deployment features of JBoss, I generally use SFTP and Hudson provides a great plugin for this.
5. Add a project artifact repository
This is probably the most controversial of the steps outlined here. The concept of an artifact repository is probably familiar to most people given the broadened use of Maven, but may still be unfamiliar to some. Maven repositories allow you to store project artifacts including POMs, jars, wars, ears, etc. in a structured format that incorporates naming conventions and versioning. This allows you to archive versions of your software products over time while automating dependency management as dependencies and versions change.
What it requires:
- A server to install the artifact repository with the disk space necessary to store archives over time. Popular server choices include Artifactory and Nexus.
- Integration of dependency management into your build. If you are using Ant, the Ant Tasks for Maven are useful or you can use Maven itself. Ivy is also a popular choice.
So what would you recommend? What processes and tools do you feel are essential to all development teams?