|
Constant
integration of code with the rest of the system gives you immediate
feedback on your work. This gives you the confidence in the code,
says Pradyumn Sharma in his series on Extreme Programming
In my last two articles, we looked at testing
and refactoringtwo out of the 12 key practices of Extreme
Programming (XP). Testing lets you write new code with confidence,
while refactoring helps you continuously clean up your existing
code. We now look at another important best practice of software
developmentcontinuous integration.
Imagine that you are part of a development team.
You come to the office one morning, and take up some class that
needs to be implemented. Let us say, it is for some application-specific
functionality, such as a validator to check whether a given book
can be issued to a given member in a library (some books may be
meant for students of a specific semester only; some books can only
be issued to adult members, etc).
You write the unit tests, automate them with
some testing framework such as JUnit. Then comes the writing of
the actual code for your class. You run the unit tests to verify
the results, and possibly after a few rounds of modify-run-debug
cycles, you get them all to pass. A task is completed.
What should you do next? Integrate your code
with the rest of the system. Do not proceed to the next programming
task unless you integrate your code?
You wo-uld like to know right away, when your
mind is fresh whether the code wo-rks well with other code in the
system, rather than finding out days or months later, when various
developers bring their code together, to discover that some assumption
you made about some other areas of code is not valid, and things
do not work together.
Building and testing the system
How do you integrate your code with the rest
of the system? You can keep one computer dedicated for this purpose
in your project. When you are through with your programming task,
you load your code (check in) as well as your tests to this integration
machine. You run, not only the tests on your new code, but all the
existing tests as well.
If all the tests pass, then you can consider
the task accomplished, and move on to the next programming task
on hand. But if any test fails, even if it is in some code that
you have not modified, you know that your code is the culprit, because
all the tests were passed before you loaded your code.
This means that you restore the source code and
tests on the integration machine to the earlier state, and start
working on your code again, to make it work properly.
Integration after
modifications
The same holds if you are modifying some existing
code to add new functionality, to improve some performance, to fix
a bug, etc. You make modifications to your code and integrate immediately
with the other code in the system, and test the entire system all
over again.
As an example illustrating the importance of
continuous integration with code modifications, suppose you have
implemented some class, say Stack. Somebody else has extended this
class to create a different special-purpose class called MyStack.
Later, you may modify the code of your Stack
class for improving its performance, but the code change may result
in some malfunction in the MyStack class. If you integrate your
modified Stack class with the system, i.e., rebuild the executable
and run all the test cases again, you will find the problem immediately.
This kind of continuous integration gives you
immediate feedback and build confidence in the code.
This also helps you monitor the progress of the
system. After all, how can you say that some programming task has
been completed unless you can test it in conjunction with the rest
of the code in the system.
It is recommended that you integrate and test
all the code in a system every few hours, or at least once a day.
If you integrate frequently, less than once a day, then you are
likely to spend more time chasing bugs or other problems that are
introduced today.
Automating integration
Following this practice of continuous integration,
once a day or more frequently, is not at all difficult. For those
who are not used to it, the initial impression may be that one ends
up spending a lot of time in such integration, but the fact is that
otherwise, you will end up spending even more time at a later stage.
The process of integrating or rebuilding the
entire system at least once a day is a common best practice of many
lead-ing software development organisations.
Microsoft is one such organisation that strictly
follows the practice of daily builds of all ongoing projects.
The practice of continuous integration is well
supported by the other two practices discussed in the previous two
articles of this series: testing and refactoring. Without automated
test suites, you cannot verify whether your code integrates seamlessly
and flawlessly with the rest of the code. Similarly, refactoring
of your code helps in improving the quality of code in the system,
not in isolation, but in relation with other parts of the system.
The process of continuous integration lends itself
well to automation. One useful tool for automating the steps of
building the executable of the system and running all the tests
is CruiseControl, an open source project from ThoughtWorks Inc of
the US. This tool, available for download from cruisecontrol.sourceforge.net,
can be used by team members for checking the code modified by them
for rebuilding and automated testing. Once the executable has been
rebuilt and the tests run, the tool can send mail to the developer
who submitted the code. The results can also be viewed using a Web
interface.
Pradyumn Sharma is the CEO of Pragati Software,
Mumbai. He is a trainer and consultant in the area of object technology
and development methodologies. E-mail: pradyumn.sharma@pragatisoftware.com
|