Introducing change in a large and complex system is often tricky. Adding new features or fixing old issues with every new iteration may affect existing product functionality. To achieve a certain level of quality, proper testing is pivotal. Manual testing can be time-consuming, requiring additional investments in human resources.
In our previous case study, we talked about how to reduce the time spent on regression testing and enable QA engineers to achieve better test coverage regularly. In this part, we’re going to focus on how to automate steps in the software delivery process with continuous integration.
For our client, we developed a social platform. The challenge was to help deliver quality and stable product.
The platform was in its growth phase with a number of additional features. There was an increased amount of dependencies in the system, which led to the fact that sometimes writing new code and refactoring was incompatible with the existing code. For all that, manual testing was giving a slow response.
In such circumstances, our product team understood the risks of errors and bugs when implementing the new functionality was high. Changing requirements resulted in the refactoring part of the system so that it could meet the new requirements. Each refactoring affected the finished functionality. In addition, regression testing was increasing. The QA team was required to spend less time on regression testing each time when refactoring was performed.
We wanted to improve the speed and consistency of delivery, as well as the QA team productivity and efficiency.
The task was to improve the quality of the product by discovering hidden bugs more efficiently and streamline the testing process to get better results in less time at a more affordable cost. Also, the client wanted to improve the test suite structure and increase test coverage. That is where continuous integration comes into the picture.
In order to achieve objectives, avoid defect deployments, and ease releases, we’ve suggested turning our current pipeline to CI/CD.
Continuous integration (CI) is a development practice of automating the build and testing the code on each update. It allows us to work in small increments and detect and resolve errors at the early stages.
Once the integration is complete and all tests have passed, we add continuous delivery (CD), where code changes are automatically prepared for the deployment for all the servers. CI/CD helps our team to be more productive when shipping software with quality build. Changes to the pipeline brought corresponding changes to the build system's structure and flow.
Multiple stages have been separated to parallelize the work, speed up the process, and make it close to DevOps standards. Additionally, this approach allowed us to receive faster feedback and do work more effectively. We also prepared a scalable test automation framework that we integrated with our CI system. It enabled developers to launch it locally against any built part of the system. This was achieved by using a containerized environment (docker) for the data aggregation and test execution.
Documentation is an important part of agile software development projects. One of the reasons for writing automated tests is that tests can act as useful documentation for a system. A well-configured CI allowed us effortlessly to obtain up-to-date documentation that evolves naturally with a system.
We managed to reduce the time for evaluating the quality of the commit tremendously (compared to manual testing approach), thus reducing the cost of fixing critical bugs by 20 times.
A well-configured CI allowed us to create a “safety net” for the development team when refactoring and implementing new functionality.
We automated the deployments and builds as well as all documentation so it stays relevant.
We achieved a reduced test response time.
We improved the product quality - the team discovered and fixed issues immediately.
The overall system architecture is constructed from separate blocks with minimal dependencies.
This solution helped us to achieve a more efficient build system thanks to separated components and clean CI workflows.