Test Driven Software Development
Like Chinese philosophy Yin and Yang, Coding and testing support each other. Here I want to introduce a method to increase the rate of software project success. It is a critical thinking in programming, an agile methodology on a micro-scale level. What is it? In every line of code, every loop or conditional block, we look for multiple solutions. For each solution, we evaluate possibilities of going wrong. Pick the most reliable one. It helps us remove most of code vulnerability at beginning.
Knowing how to test is more important than knowing how to coding. A good function is stable, fast and, requires less memory and computing resources. It is not necessary to be complicated or has difficult API functions under the hood. Usually, it has less code and seems to be simpler than the rest. And it is the result of various tests and trying different methods. We choose the best way to compose the code base on various tests. It ensures robust software system with less vulnerability.
Let us say there is a project that send human beings to the Mars. If we are part of the project and our responsibility is to land the spaceship on the surface of the planet safely. How to make sure 'Landing Function' work without any deadly 'bug'? To us, what is the most important thing for it? It is not the landing gear; it is not the parachute. It is the tests. Under different situations, we performing hundreds or thousands of tests to validate each equipment. Find those thousands testing cases is the most difficult and important task. We need to find as close condition as possible under which when landing the spaceship on the Mars. The temperature, the speed of the spaceship, the chemical in the air, etc. Test materials under all sorts of combined circumstances. Any possibility that can go wrong, we will let it fail in the test.
When we solve a problem or fix bugs, we do the same thing. We do some research. By doing some research, we guess the cause of a problem. Then, we try to prove it with many tests. If the test results are positive, then, we came to a conclusion. Otherwise, we continue guesses and tests. Insufficient tests may lead us to a wrong conclusion.
Again, the tricky thing is how we test it. It is same when building new functions or modules. Whenever there is a solution, we put it under different conditions and validate it. We cover it with enough test cases. Like Chinese philosophy Yin and Yang, Coding and validating support each other.
When building a complex function, we may divide it into many baby steps. Each step is important to the overall success. Exhaust the ways testing each step to make sure each one is good. The result of the previous step can safely serve the next step. Finding a good way to test each step is crucial. Because there are many ways to do a thing. We need to choose the best one with tests. To each baby step, there can be a dozen ways to take. Able to find the most reliable way is a merit of a good software developer or a project leader. When pushes code to production, it can be way more complicated and possible to break. As laws of Murphy, anything that can go wrong will go wrong. So, have multiple test scenarios prepared for the smallest function unit. It is essential to make our code safe and sound. We will never overestimate the importance of it.
When it comes to a complex function, dividing it into small functional units that are easy to verify. Let's say the CYouTube project. We divide it into multiple steps and sub-steps. Each step has an easy and clear goal to achieve.
Each of those major Steps has multiple sub-steps. For example, pulling data from YouTube has following sub-steps.
Each of the sub-task or major task is easy to verify. Whenever, something goes wrong, we can follow the steps and find the broken one. From large scale to small, we can use this methodology. When we practise it more, our minds become more capable to find those steps with clear goals; We will foresee the problem when we choose the way to implement each step. That is before we do some real coding; That is how we can develop software that requires less maintenance.
Test-driven development (TDD) relies on the repetition of a very short development cycle. The developer writes an automated test case before writing code. Our approach is a step ahead of it. When thinking about the solution, we find test cases first. Passing those test is the goal of next step - coding. We start think about test case when we read the requirement document. When we write code, we are thinking about how to break it. Whenever we finish a function, it went though many verification tests by ourselves. When it finishes, we have a much better chance to have a fully functioning module. If it does not work out, we can always return to each step and find the broken link by reiterating the verification process. I believe it is the most efficient way to develop something.