Many people talk about phased or incremental integration, or top-down vs bottom-up, as if it were a matter of taste (like which shirt to wear), or perhaps an article of conviction (like which end of a soft-boiled egg you should crack). Nothing could be further from the truth:
Integration strategy is also often discussed as if we had a bunch of complete components, and were just trying to figure out the order in which we should add them to the system. In new products, components usually continue to evolve after their initial integration. The integration strategy must order, not only the components, but the implementation of features and functions within each component.
Integration strategy is a crucial and inseparable element of the product architecture and project development plans. A good integration strategy is one that, in combination with the architecture:
Many discussions of integration strategy are predicated on the assumption that we are combining multiple components that have never seen one-another before. This is probably the worst-case scenario, and the one that demands the most thorough analysis. It is not, however, a common situation. More common are situations where there is an existing system, into which a few new components and functions are to be introduced. In such cases, the integration will be incremental, and the starting point is a given ... but careful consideration may still be required in the introduction of new functionality.
There are three principles of testing that bear on integration strategy:
All three of these principles follow from the simple realizations that it is easier to test a small amount of code than a large amount of code, and it is easier to test a change, when the pre-existing code was known to be working.
We can always build a special test harness to exercise new code, but it is often preferable to exercise the new code in a complete system:
Thus, for each component, we must ask ourselves how we will exercise it in its early stages of development. An integration strategy that provides an exercise frameworks for new components as they are added is a good one. Note, however, that custom exercise harnesses are not always a bad idea. Some components have such rich and complex interactions with other components, that unit testing can be performed much more efficiently and effectively with a custom exercise harness. In these cases, the component should be designed with the exerciser in mind, and the exerciser should be built to last ... because it may continue to be the preferred means of unit testing changes to the component, even after integration has completed.
It is often desirable to verify that a component correctly implements the specified interfaces with unit test cases (whether applied to the component in-vacuuo or in-situ). Many problems, however, result from misunderstandings of the interface specifications. The best way to shake out such problems is by combining the interacting components and exercising them together. In planning the integration order of components and functionality, we should ask when we will be able to exercise each interfaces, which components need to be present (with what level of functionality) to begin such exercising, and how we will drive the testing. The integration strategy should ensure that as soon as two components are available, it will be possible to exercise and observe their interactions.
It is prudent to schedule riskier activities sooner. If it is going to take a while to get a tricky component right, starting it sooner reduces the likelihood that those difficulties will cause us to miss our schedule. If we expect to encounter problems in the construction of a new component, we have to be prepared to change our plans in response to those problems. Conducting those investigations up front gives us the opportunity to change our designs before building the other components that might be affected by those changes. There may be other reasons to schedule some components sooner than others (e.g. we plan to use them as learning exercises, or they may require resources that will not be available later). The point is that external considerations may determine the relative order in which some components are to be built.
The product integration strategy must acommodate such requirements, making it possible to integrate (giving them set of components with which they can be combined) and test (providing a framework for exercising them and observing their behavior) components in the order in which their construction must be scheduled.
The architecture of a system resolves its functionality into distinct components, and defines the functions of each component, and the interfaces between them. When we talk about integration strategy, it is natural to describe that strategy in terms of which components will be introduced, in which order, with what subsets of their specified interfaces and functionality.
When we define each component, we must consider:
The architecture of the system, and each of its sub-components must be designed to support an integration strategy. The integration strategy dovetails a testing strategy with an implementation schedule. The integration strategy is ultimately dictated by the schedule and the architecture. None of these can be designed without considering the others.
As I have said may times before, architecture is compromise.