Lecture
Integration
Industrial-strength software projects require the creation of families of programs. In the course of development, prototypes and releases are produced. Very often each developer has his or her own view of the system being developed.
The previous chapter explained that in the object-oriented development process integration is rarely carried out all at once. Usually there are many small integrations, each of which corresponds to the creation of a new prototype or architectural release. Each new release incrementally builds upon the previous stable releases. "With iterative development, one first builds a software product that satisfies only a few of the final requirements, but which is structured in such a way as to make it easier to satisfy all the requirements later and thus achieve greater adaptability" . From the end user's point of view, the stream of releases flows out of the macro process. Each successive release supports more functions, and eventually they evolve into the finished system. From the point of view of someone watching the process from the inside, many more releases are produced, but only some of them will be "frozen" in order to stabilize the system's most important interfaces, and taken as a baseline for further work. Such a strategy makes it possible to reduce development risk and speeds up the discovery of architectural problems and bottlenecks at early stages.
For large projects an organization may prepare internal releases of the system every few weeks, and releases for the customer every few months, according to the needs of the project. In a stable state, a release consists of a set of compatible subsystems together with the corresponding documentation. One may begin building a release provided that the project's main subsystems are sufficiently stable and their joint interaction is sufficiently well coordinated to provide a new level of functionality.
Configuration management and version control
Consider the stream of releases from the point of view of a developer engaged in creating some subsystem. He has the current version of this subsystem. Consequently, he must have at his disposal at least the interfaces of all the subsystems he imports. When the working version stabilizes, it is handed over to the integration team, which is responsible for assembling the compatible subsystems into a whole system. Eventually the set of subsystems is frozen, taken as a baseline, and included in an internal release. The internal release becomes the current operational release, available to all developers who need to carry out further refinement of their parts of the implementation. Our developer meanwhile can work on a new version of his subsystem. In this way development can proceed in parallel and remain stable thanks to clearly defined and protected subsystem interfaces.
Implicit in this model is the assumption that the unit of version control is not an individual class but a group of classes. Experience shows that managing versions of classes is far too hopeless a business, since they are too dependent on one another. It is better to release versions of related groups of classes, or more precisely of subsystems, since clusters of classes in the system's logical model map onto subsystems of the physical model.
At any moment in a system's development there may exist several versions of its subsystems: the version for the release currently under development, the version for the current internal release, the version for a subsequent release intended for the customer, and so on. This sharpens the need for sufficiently powerful configuration management and version control tools.
The notion of "source code" covers not only program text but also all the other products of object-oriented development: requirements specifications and class, object, module and process diagrams.
Testing
The principle of continuous integration applies to testing as well, which is also carried out throughout the entire development process. In the context of an object-oriented architecture, testing must cover at least three areas:
Involves testing individual classes and mechanisms; it is the responsibility of the engineer who implemented them.
Involves testing whole categories or subsystems; it is the responsibility of the person in charge of the subsystem; subsystem tests may be used regressively for each newly released version of the subsystem.
Involves testing the system as a whole; it is the responsibility of the quality assurance people; system testing, as a rule, is also carried out regressively.
Testing should focus on the external behavior of the system; its secondary goal is to determine the boundaries of the system in order to understand how it may fail under certain conditions.
Comments