Posted by william.vergara on 06 Jun, 2019
The earliest and continuous delivery of value to the client poses great challenges to software development teams. The construction of the functionalities that materialize such value, supposes several hours of work distributed among the team members. At the end of the development process, each member makes their individual contributions into a common repository; giving rise to the functionality. The time to perform this integration will be proportional to the size of the team and the complexity of the development; delaying delivery to the client. This way of working is inefficient and end up delivering large changes and less frequently than the team supposes.
One possible solution is Continuous Integration. However, it is important to understand that Continuous Integration is a practice and not the use and implementation of an integration server; this will be the final step of the adoption process.
Integrating into the main repository every small change reduces the possibility of errors. In addition, the ideal state would be to run automatically a set of test to verify that the construction is not broken.
Implementing this way of working poses great challenges to the team and the organization. Since the continuous integration is a developer practice performed daily or more than once per day, it is important to focus on the people As a result, every single integration to the main repository makes the system grows; at the same time that the repository remains ready to deploy if it is necessary.
It is natural to assume the integration as one of the final steps to be carried out since only until the end of the development the results are tested; giving to the developer the confidence and the security to integrate its work. To avoid this behaviour; it is important to change the size of the tasks to a smaller size, in this way the tests, the detection of errors and their correction will be easier and quicker.
Guiding the developer to perform the maximum fractionation of their tasks will facilitate their adoption of this practice. Similarly, by making their contribution visible through several integrations during the day will strengthen the team motivation and confidence.
As the main repository is sacred, it should be as clean as possible, so it is important to manage versions as a security backup before integrating. The repository contains the source code and configuration files; so be sure to include the last version of the code that works correctly.
Obviously, the results of Tests help to decide this point, but what Tests should be performed?
There are different types of tests and each one is focused on a different stage of development of the cycle. All are important and only the performance of the set can give a high degree of reliability. In accordance with the Mike Cohn Test Pyramid, it establishes the order, amount of effort indicated by the type of test, speed of execution and costs.
On the bottom of the pyramid, we find the Unit Tests. On this test, the methods and classes are tested independently, so their scope is limited. Integration and Acceptance Tests make up the service layer, integration tests verify that several components together have the expected behaviour that could include other services. The acceptance tests instead are focused on business cases. Finally, the User Interface Tests check the operation from the user's perspective.
As testing implies a cost in the time of development, it is better to cover as much as possible through Unit Tests that are faster to create and execute. In addition, this kind of test can give quick feedback to the developer, avoiding entering errors from the beginning of the development cycle.
During the first launches, it will be possible to run a set of complete tests, but as the product grows testing becomes complex. It is important to keep a sequence and be sure that Tests evidence is organized properly to provide quick information to the developer and the right environment for execution. Be sure that the core of the product has been identified and fully tested.
The highest priority during the process will be to identify and correct if the compilation of the main branch gets to break with any integration. Otherwise, it would make more difficult to understand further breaks and for sure it will present more flaws.
It is common to fall into the practice of delaying integration to avoid breaking the build. On the contrary, constant integration helps to identify errors and understand its cause and its prompt correction. Adopting this practice also helps to learn in the process leaving the same errors on the past. The creation of a multifunctional team and the permanent collaboration of its members will help at this point. An essential practice to implement is Trunk Based Development.
Technical excellence can be seen as a set of three components: Technique, the skill of the developer in the technique and the team's sense of developers. These aspects are necessary and binding during the adoption process of Continuous Integration.
Once the team focuses its work on the minimum unit of work and adheres to a set of automatic tests, it will guide the efforts in increasing the coverage of the unit tests in the product. This practice will lead to the application of design patterns to reach low coupling and high cohesion on the components. As a result, it allows creating a repository with reusable components including an automatic test set.
In addition, the team will have space and the opportunity to experiment with evolving Unit Tests in Test Driven Development (TDD); including in this way the tests from the beginning of the development. Another possibility will be to include next to TDD, Behavior Driven Development (BDD) also to include acceptance tests from the development itself.
The process of adoption of integration involves the implementation of a series of techniques by the team members. The permanent practice of such techniques will strengthen the skills and the sense of team and commitment.
The adoption of Continuous Integration will optimize the time of the developing cycle by identifying and resolving conflicts in an immediate way. As a result, the amount of time spent correcting errors will be dedicated to forming a good set of tests.
By integrating small changes the scope is reduced; enabling the team to collectively understand conflicts and the incremental growth of the product itself. The exchange of knowledge among developers is motivated by the process since the changes are easier to digest.
In Atlanticsoft as agile manifesto followers, we implement Continuous Integration. Through this practice we help our clients to optimize cost and times, producing more stable solutions.