In the previous post, I discussed how Continuous Planning and Prioritization enable teams to stay responsive and aligned with changing business and customer needs. Now, we’ll look into two more areas of the Continuous Software Engineering framework (see paper): Continuous Development and Continuous Quality Assurance.
These activities ensure that teams continuously build and maintain high-quality software and are directly connected with the craftsmanship and quality attributes discussed in a previous post.
Continuous Development
In the Continuous Software Engineering (CSE) framework, Continuous Development is about “building”. It includes practices that ensure software is iteratively delivered to users, such as Continuous Integration (CI), Continuous Delivery (CD), and Continuous Deployment (CD) - which I assume are familiar to most of you.
Continuous Integration (CI) ensures that new code is regularly integrated into the main (or master) branch to minimize integration issues and maintain a consistently functioning codebase. CI tools such as Jenkins or CircleCI allow you to integrate, build, and deploy the code to a selected environment.
Continuous Delivery (CD) refers to having code merged on the main (or master) branch ready to be released for production at any time. The code is automatically pushed and deployed to different environments, reducing lead times (you can read more here about the Change Lead Team DORA metric) and enabling faster delivery of new features. In Continuous Delivery, the deployment to production is not automated; the production push is typically a manual step.
Continuous Deployment (CD) can be simplified as Continuous Delivery plus automated deployment to production, eliminating the need for manual intervention when deploying.
However, beyond CI/CD, two critical aspects are often less discussed: Continuous pull requests and Continuous Architecture Evolution.
Writing Continuous Pull Requests (PRs) is the habit of engineers submitting PRs frequently and keeping them small and manageable. When PRs are continuously created, reviewed, and merged, it drives productivity, collaboration, and learning among the team members working on the same codebase. It prevents risky merges and makes code reviews more efficient and focused.
For example, in a group I led in the past, we adopted this practice: engineers were encouraged to submit incremental PR changes every day or other day behind Feature Flags (more on Feature Flags here)- a features flag was the first thing to be created for a feature. This practice significantly reduced integration issues, promoted knowledge sharing (see this previous post about the value of knowledge sharing), and maintained a high standard of code quality.
Continuous Architecture Evolution is about revisiting high-level design decisions in a continuous matter. Due to the ever-changing business, product requirements, and engineering discoveries, an active codebase needs to evolve the architecture or design of different pieces.
A critical practice in this area is continuously reviewing Tech Design Documents (TDD). TDDs are living documents that outline the architecture and technical decisions of a product feature. They are continually refined as the architecture evolves. In my experience, regularly revisiting these documents for active features or components helps teams ensure that architectural decisions remain flexible according to the product direction and discoveries.
For example, while managing the team working on the initial development of the Spotify Ad Manager (called Ad Studio back then), we frequently revisited our tech strategy doc along with the different releases (from alpha to beta to public release). For example, in the Payments area, we moved from leveraging integration with Paypal to integrating with Adyen and then to integrating with the internal Spotify payments API. We could make the necessary changes by continuously reviewing our design before they became more considerable technical debt.
Continuous Quality Assurance
Building software doesn’t stop at writing code; quality is also an integral part of the continuous process. Continuous Quality Assurance (QA) ensures that software is tested and validated at every step of the development cycle. This approach is far more effective than the traditional waterfall approach that typically introduces testing as a final step.
Continuous Verification and Validation (V&V) ensures that code changes meet quality standards before they reach users.
Continuous verification focuses on verifying the actual behavior adheres to the expected behavior for specific requirements. Continuous validation ensures that the product meets the users’ needs and delivers the intended business value.
A combination of automated testing and dogfooding are good examples of practices within continuous quality assurance.
Automated testing integrated into the CI pipeline ensures that as developers continuously merge code into the main branch, the system automatically verifies the functionalities and discovers regression issues and performance bottlenecks.
For example, in every team where we had a comprehensive test suite with unit, integration, and end-to-end tests, the teams could deploy features faster while maintaining confidence in the quality of the software. Engineers could focus on delivering new features, knowing that our test suite would catch regressions or performance issues early.
Dogfooding allows you to experience the product like your customers; see my previous article for more details. For example, at Snap, we relied heavily on dogfooding to release features safely.
Finally, manual QA should not be overlooked either. Techniques like exploratory testing and user feedback loops ensure that edge cases are tested before production releases.
With Continuous Development and Continuous Quality Assurance, teams can build software faster and ensure that quality is maintained throughout the process. Practices like Continuous Pull Requests and Continuous Architecture Evolution contribute to having teams excel in craftsmanship and adaptability, and embedding quality assurance into every step provides better confidence in what is delivered.