Lately I’ve been thinking what makes for effective software development practices lately so I thought I would summarize my ideas in a post.
Code Reviews
Code reviews are an essential aspect of any effective software development effort. They are not only useful for identifying questionable code but they provide other team members with the opportunity to learn about areas of the system that they may not be familiar with. Code reviews should be focused on more than just finding defects; conformance to coding standards and reliability are also critical.
Any refactoring tasks that arise during a code review can usually be handled in the next iteration. Code reviews are also best conducted in the absence of management figures. You know the code review process is working when you hear lots of WTFs.

Unit Tests
Unit testing should be utilized whenever possible to prove out functionality of code at the most basic level. Typically, this would mean writing individual test programs that exercise all of the public functions of a single class. Unit tests should not have dependencies on external components such as databases or active processes. They need to be as standalone as possible. If necessary, employ mock objects to mimic the behavior of classes that the tested class relies upon. If possible, develop unit tests in advance of coding as Test-Driven Development (TDD) dictates. Unit tests should run quickly and would ideally be automatically triggered after every checkin to your source control system.
Component Tests
Component tests verify larger aspects of the system and will generally involve external components such as the network or databases. Component tests still do not run against the full system, however. For example, you could build a component test to verify the model portion of a Model-View-Controller (MVC) system. The component test would verify that calling methods on classes in the model results in specific rows being added to specific tables in the database. Again, components tests should be run after every checkin but this may not be practical if they take a while to run.
System Tests
System tests exercise the final product fully. Typically, this would involve installing the system from scratch and putting it through a battery of tests. This could be performed by dedicated QA resources or, ideally, by an automated testing tool.
Refactoring
To keep a software system from becoming brittle and unmanageable, regular refactoring is an absolute requirement. Target areas of the system that are frequently responsible for defect reports from the field. Encourage the development team to carefully design and think through refactoring efforts. The end result should almost always be smaller and faster code that will be more reliable.