Continuous integration, delivery, and deployment

TDD goes hand in hand with CI, continuous delivery, or CD. Differences aside, all three techniques have similar goals. They are all trying to foster the continuous verification of production readiness of our code. In that respect, they are very similar to TDD. They each promote very short development cycles, continuous verification of the code we're producing, and the intention to continuously keep our application in a production-ready state.

The scope of this book does not permit us to go into the details of those techniques. Indeed, a whole book could be written on this subject. We'll just briefly explain the differences between the three. Practicing CI means that our code is at (almost) all times integrated with the rest of the system, and if there is a problem it will surface quickly. If such a thing happens, the priority is to fix the cause of that problem, meaning that any new development must take lower priority. You might have noticed a similarity between this definition and the way TDD works. The major difference is that with TDD, our primary focus is not the integration with the rest of the system. The rest is the same. Both TDD and CI try to detect problems fast and treat fixing them as the highest priority, putting everything else on hold. CI does not have the whole pipeline automated, and additional manual verifications are needed before the code is deployed to production.

Continuous delivery is very similar to CI, except that the former goes a bit further and has the whole pipeline automated, except the actual deployment to production. Every push to the repository that passed all verifications is considered valid for deployment to production. However, the decision to deploy is made manually. Someone needs to choose one of the builds and promote it to the production environment. The choice is political or functional. It depends on what and when we want our users to receive, even though each is production-ready.

"Continuous Delivery is a software development discipline where you build software in such a way that the software can be released to production at any time."
– Martin Fowler

Finally, CD is accomplished when the decision about what to deploy is automated as well. In this scenario, every commit that passed all verifications is deployed to production—no exceptions.

In order to continuously integrate or deliver our code to production, branches cannot exist, or the time between creating them and integrating them with the mainline must be very short (less than a day, preferably a few hours). If that is not the case, we are not continuously verifying our code.

The true connection with TDD comes from the necessity to create validations before the code is committed. If those verifications are not created in advance, code pushed to the repository is not accompanied with tests and the process fails. Without tests, there is no confidence in what we did. Without TDD, there are no tests to accompany our implementation code. Alternatively, a delay in pushing commits to repository until tests are created but in that case, there is no continuous part of the process. Code is sitting on someone's computer until someone else is finished with tests. Code that sits somewhere is not continuously verified against the whole system.

To summarize, continuous integration, delivery, and deployment rely on tests to accompany the integration code (thus, relying on TDD) and on the practice of not using branches or having them very short-lived (very often merged to the mainline). The problem lies with the fact that some features cannot be developed that fast. No matter how small our features are, in some cases it might take days to develop them. During all that time, we cannot push to the repository because the process would deliver them to production. Users do not want to see partial features. There is no point having, for example, part of the login process delivered. If one were to see a login page with a username, password, and login button, but the process behind that button does not actually store that info and provides, let's say, an authentication cookie, then at best we would have confused the users. In some other cases, one feature cannot work without the other. Following the same example, even if a login feature is fully developed, without registration it is pointless. One cannot be used without the other.

Imagine playing a puzzle. We need to have a rough idea of the final picture, but we are focused on one piece at the time. We pick a piece that we think is the easiest to place and combine it with its neighbors. Only when all of them are in place is the picture complete and we are finished.

The same applies to TDD. We develop our code by being focused on small units. As we progress, they start taking a shape and working with each other until they are all integrated. While we're waiting for that to happen, even though all our tests are passing and we are in a green state, the code is not ready for the end users.

The easiest way to solve those problems and not compromise on TDD and CI/CD is to use Feature Toggles.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.203.96