Combining parts of a software product to form a whole is called integration. It is also one of the most troublesome tasks and it rarely goes smoothly.
In terms of timing and frequency, there are two general approaches to integration: late and one-time, early and frequent.
Late and one-time: wait till all components are completed and integrate all finished components near the end of the project.
This approach is not recommended because integration often causes many component incompatibilities (due to previous miscommunications and misunderstandings) to surface which can lead to delivery delays i.e. Late integration → incompatibilities found → major rework required → cannot meet the delivery date.
Early and frequent: integrate early and evolve each part in parallel, in small steps, re-integrating frequently.
Here is an animation that compares the two approaches:
Big-bang integration: integrate all components at the same time.
Big-bang is not recommended because it will uncover too many problems at the same time which could make debugging and bug-fixing more complex than when problems are uncovered incrementally.
Incremental integration: integrate few components at a time. This approach is better than the big-bang integration because it surfaces integration problems in a more manageable way.
Here is an animation that compares the two approaches:
Give two arguments in support and two arguments against the following statement.
Because there is no external client, it is OK to use big bang integration for a school project.
Based on the order in which components are integrated, incremental integration can be done in three ways.
Top-down integration: higher-level components are integrated before bringing in the lower-level components. One advantage of this approach is that higher-level problems can be discovered early. One disadvantage
is that this requires the use of
Stub: A stub has the same interface as the component it replaces, but its implementation is so simple that it is unlikely to have any bugs. It mimics the responses of the component, but only for the a limited set of predetermined inputs. That is, it does not know how to respond to any other inputs. Typically, these mimicked responses are hard-coded in the stub rather than computed or retrieved from elsewhere, e.g. from a database.
Bottom-up integration: the reverse of top-down integration. Note that when integrating lower level components,
Sandwich integration: a mix of the top-down and the bottom-up approaches. The idea is to do both top-down and bottom-up so as to 'meet' in the middle.
Here is an animation that compares the three approaches:
Suggest an integration strategy for the system represented by following diagram. You need not follow a strict top-down, bottom-up, sandwich, or big bang approach. Dashed arrows represent dependencies between classes.
Also take into account the following facts in your test strategy.
HospitalUIwill be developed early, so as to get customer feedback early.
HospitalFacadeshields the UI from complexities of the application layer. It simply redirects the method calls received to the appropriate classes below
IO_Helperis to be reused from an earlier project, with minor modifications
OutPatientcomponent has been outsourced, and the delivery is not expected until the 2nd half of the project.
There can be many acceptable answers to this question. But any good strategy should consider at least some of the below.
HospitalUIwill be developed early, it’s OK to integrate it early, using stubs, rather than wait for the rest of the system to finish. (i.e. a top-down integration is suitable for
HospitalFacadeis unlikely to have a lot of business logic, it may not be worth to write stubs to test it (i.e. a bottom-up integration is better for
IO_Helperis to be reused from an earlier project, we can finish it early. This is especially suitable since there are many classes that use it. Therefore
IO_Helpercan be integrated with the dependent classes in bottom-up fashion.
OutPatientclass may be delayed, we may have to integrate
PatientMgrusing a stub.
TypeCseem to be tightly coupled. It may be a good idea to test them together.
Given below is one possible integration test strategy. Relative positioning also indicates a rough timeline.
Consider the architecture given below. Describe the order in which components will be integrated with one another if the following integration strategies were adopted.
a) top-down b) bottom-up c) sandwich
Note that dashed arrows show dependencies (e.g. A depend on B, C, D and therefore, higher-level than B, C and D).
Build automation tools automate the steps of the build process, usually by means of build scripts.
In a non-trivial project, building a product from source code can be a complex multi-step process. For example, it can include steps such as to pull code from the revision control system, compile, link, run automated tests, automatically update release documents (e.g. build number), package into a distributable, push to repo, deploy to a server, delete temporary files created during building/testing, email developers of the new build, and so on. Furthermore, this build process can be done ‘on demand’, it can be scheduled (e.g. every day at midnight) or it can be triggered by various events (e.g. triggered by a code push to the revision control system).
Some of these build steps such as to compile, link and package are already automated in most modern IDEs. For example, several steps happen automatically when the ‘build’ button of the IDE is clicked. Some IDEs even allow customization to this build process to some extent.
However, most big projects use specialized build tools to automate complex build processes.
Some popular build tools relevant to Java developers:
Some build tools also serve as dependency management tools. Modern software projects often depend on third party libraries that evolve constantly. That means developers need to download the correct version of the required libraries and update them regularly. Therefore, dependency management is an important part of build automation. Dependency Management tools can automate that aspect of a project.
Maven and Gradle, in addition to managing the build process, can play the role of dependency management tools too.
An extreme application of build automation is called continuous integration (CI) in which integration, building, and testing happens automatically after each code change.
A natural extension of CI is Continuous Deployment (CD) where the changes are not only integrated continuously, but also deployed to end-users at the same time.
Some examples of CI/CD tools: