Testing and Chaos Engineering
As development with Agile methodologies has gained momentum over the past decade and a half, the software development industry is progressively more focused on continuous delivery; products must be constantly updated to remain competitive, and that requires creating greater efficiency in the overall development and release processes. TDD (Test Driven Development) and CI (Continuous Integration) were originally created as part of the Extreme Programming (XP) methodology with the aim to produce higher quality code, and thus, make deployments easier.
Most developers generally don’t start writing tests, some don’t write tests at all! Test Driven Development is a software development process where you use testing to develop in small cycles. It is a technique where you describe the behavior of your code before you implement it.
Test-Driven Development Cycle
The first step or step 0 is defining the user’s requirements. From these requirements, we can enter the proper TDD cycle. RED, GREEN, REFACTOR. This is the TDD mantra that we are going to follow until our code meets the desired quality and functionality. So first you write just enough test code to make it fail, then you write just enough production code to make the test work, and finally we refactor. Step 3 could be skipped if there is nothing to refactor. But if you write more complex code, you should spend time refactoring your code to make it more readable and clean while still making sure it passes the tests.
Why Test-Driven Development?
- Clear Requirements. You can not do TDD when you don’t understand the requirements. This forces you to clarify the requirements and create good thought out user stories.
- Refactoring and Maintenance. TDD also makes refactoring and maintenance much easier. As all functionality is covered by tests, an error is easily detectable.
- Modular code. When the code is modular and the changes impact smaller pieces of functionalities, the risk associated with breaking other parts of the code decreases.
- Documentation. You don’t require much documentation because your tests describe how your code works.
- Minimum Code. TDD also ensures that only necessary code is produced. The code that is written to successfully pass tests is the minimum possible, and over-coding is avoided.
- None or minimal debugging. Your code most of the time works so no 4-hour sessions of debugging are needed.
Test-Driven Development Disadvantages
- Development Speed. One of the most debated cons in the TDD process is development speed. Starting a project with TDD might take more time than starting it with a conventional development, but that speed improves in the long run.
- Increased Maintenance. When working with TDD, maintenance of test code is essential. If the product requirements shift or vary, tests associated with the functionality need to be first re-thought.
- Learning Curve. TDD can be complicated to learn and requires practice and dedication as it represents a large change from what most software engineers are accustomed to. It can be frustrating to begin with as it seems like a time sink.
- Team Effort. TDD needs involvement of the entire team. Either everyone in the team should adopt it, or it’s better not to attempt it.
Test-Driven Development is not a magical methodology that ensures you a perfect and clean project. It is just a tool. At the end of the day, you are the one in charge of making the decisions about the direction of your project. TDD only help you to reduce the feedback loop and minimize the time between making a decision and knowing if it was the correct option or not. When working with a team that is convinced of the benefits of using Agile methodologies and the tools offered by Extreme Programming, TDD is a great option, as in the long run, its benefits get reflected in the code quality, the delivery speed, and the count & severity of bugs and the final project.
In the past, developers on a team might work in isolation for many days or even months and only merge all of their modifications into the master branch when the work was completed. This made merging code changes very difficult and time consuming, since some times changes from contributors conflicted and bugs accumulated for a long time. Continuous Integration rose to prevent all of these problems from happening.
Continuous Integration in its simplest form, involves a tool that monitors your version control system for changes. Whenever a change is detected, this tool automatically compiles and tests your application. If something goes wrong, the tool inmediately notifies the developers so that they can fix the issue as soon as possible.
Continuous Integration Benefits
- Improve Developer Productivity. CI helps your team be more productive by freeing developers from manual tasks and encouraging behaviors that help reduce the number of errors and bugs released to customers.
- Find and Address Bugs Quicker. With more frequent testing, your team can discover and address bugs earlier before the grow into larger problems.
- Deliver Updates Faster. CI helps your team deliver updates to their customers faster and more frecuently.
The web has become more and more complex with the rise of microservices and cloud architectures, making failures much harder to predict. A system failure can cost companies millions of dollars, they could hurt the user experience and the reputation of the business. Even a single hour downtime could cost well over millions of dollars. With this challenge rose chaos engineering.
Chaos Engineering is an engineering approach studies how highly complex large-scale computer systems respond to apparently random events. This tests mainly looks into how the systems would respond under stress and fix potential failures. You literally “break things” on purpose to discover weak points and learn how to build more resilient systems with the gathered information.
Principles of Chaos Engineering
- Plan an Experiment — You start by forming a hypothesis about how your system should behave when something goes wrong.
- Contain the Blast Radius — Then, you should design the smallest test possible that will teach you something about your system.
- Scale or Squash — Finally, you must measure your system at each step. Look for signs of success or failure, everything is useful for understanding the reaction of your system’s real-world behavior.
The ultimate goal is never chaos, but reliability. Learning how a system responds to stimulus affords engineers the opportunityt to compensate by adjusting their systems to automatically mitigate against future occurrences. This practice actively seeks to limit the chaos of outages by carefully investigation how to continually make a system more robust.
When successfully combining all of these practices, an optimized development cycle can be achieved. Through Test-Driven Development, we can be sure that tests checking every aspect of the functionality of the code are being created. Continuous Integration complements this methodology bu making sure every contributor code is up to date and merged into the main branch, running tests every time this happens and alert developers whenever a bug is encountered. Because of this joint approach bugs and errors can be found very fast and easy.
Pretotyping Methodology Exercise
The following link directs to my Pretotyping PPT, where I developed 3 ideas into pretotypes.