TDD has become a fanaticism amongst Programmers. There are some sensible followers, some ardent followers, and some ardent haters. Interestingly the haters seem to hate the ardent followers/or rather the attitude of the ardent followers more than TDD itself. And that is how hate goes whether it is in SW or anywhere else.
For me, I use the term to mean write test’s while you write code so that the code is not yet set, but still malleable to be molded to be structured for better testability; and tests for me means automated unit as well as integration tests; not just unit test and coverage number has no meaning for me. The world does not have a better word that TDD; Till then I have to use some acronym and I use TDD now for lack of better; lovers and hater’s don’t burn me yet.
This is the picture in my head when I think of writing tests along with the code; everything is so malleable, it can be shaped to whatever structures you in your mind. You have created something that you wanted, and you have done justice for those who pay you for features, by having something that is testable, refactorable and of good quality.
Before I dwell more on this, I just want to highlight how I stumbled on this; I want to go back around 15 years. I was a SW developer hired in the company, for C++ programming. There was no Unit test framework for C++ at that time. My job was to add features to existing code base, and that code base was one of the most contrived examples of Object Oriented Programming that I have seen in my life. (Actually, the author could not explain it, he came next day with 7 different sketch colors to draw out the inheritance hierarchy; but that is another story). The company was Siemens Communication Software (now no longer there), and SW was telecom related SW, and we were having a pretty tough customer at that release. The development method was to implement the feature, test it manually and send it to a big testing team for system tests and then for load tests that will run a month or more. Most of the bugs were caught by system testers and SW corrected and delivered again. Before that I was working in another company again in C++ which had fewer testers; it was a small company and SW was for Telephone IVR system, directly interacting with the multi-port telephone cards in PC. A feature was done and shipped by myself/ FTPed to the customer's machine and installed. There was a time zone gap. If I made a mistake I will be called at midnight or at 2 or 3 AM and will have to go to the office and correct or give a workaround. Because the IVR was used by doctors in hospitals to record their prescription and was kind of important or the product representatives there did not care; it was coding horror at highest, and most of the time I just slept in Office itself during the release times, which was whenever a new feature was asked. Soon I realized that if I wrote Test Drivers, basically code that calls my code, I could test my software more effectively and the number of bugs decreased to almost null. And since I will be writing tests during coding, my code and design transform itself to test friendly. Soon all the night calls turned out to be some other problem or some other components problem. I left the job as fast as I could, as I got a phobia towards phone rings calling me at night(it was the older landline with the loud ‘tring tring’ sound); but it taught me a lesson for life, write your tests while you code so that you leak lesser bugs. So in the new job, I started doing this method and it paid out there also; my features had very less bugs that testers could find. Sometimes none; and it was not because I was a careful coder; it was because I was a careless coder, that I knew that without this I will be in trouble.
It was during this time that I searched on the internet about testing and found an article about Test Driven Development by a programming methodology called XTreme programming. I wrote a mail to my manager that there is something called TDD and we should practice it in the team.
I guess this is the predominant view by the majority of SW developers; I guess when we talk about TDD, we don’t mean that we write Tests first and code later as Kent Beck defined it in his book. I have actually used Test first when I have no clue on how to start off with some specific work; the last I remember was a tree coloring algorithm. But usually, it is writing tests during coding. Sometimes when I have to work on C++, I would start off writing the CMake and test harness/boilerplate setup first, so that I can start writing test cases while I develop.
However when I say to others that you need to write test during development; I don’t have a better phrase than TDD, and immediately everyone on the floor including the janitor goes stiff and yells -
“ It is hard, nobody does it (we don’t even trust that you do it)”.
Then I mumble saying that what I mean is mostly Test During Development, and I am again thrown the rule-book, or more often than not, I get the Ghost Talk effect, that is I am shouting at the top of my voice in a room, and it is as if I am a Ghost, no one hears or registers what I am saying, and everyone argues between themselves how hard or good TDD is; and how Kent Beck renamed it from Test First Programming to TDD when he wrote the book etc.
People- nobody cares about the definition. This is not a science that can be debated; just a persons opinion, at that time, though that person is a very important persons who gave us xUnit type test framework in multiple languages that we use; without which SW quality would have been horrendous and we would have to write code like Apollo 11 Code with proof that it works
Now let us hear this from Kent Beck himself; Here is a great answer from him; that will leave TDD lovers and haters both bewildered. He says- “I am not paid for tests, I write the least amount of tests. I don’t write unnecessary tests”. I don’t write a billion tests to test all scenarios.
Do you know it was Kent Beck who started the xUnit framework in SmallTalk , which was ported to Java as JUnit and popularised unit testing for all the world; Here is his strange reply for the rant by DHH (Ruby on Rails creator) that TDD is dead
https://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565#153565
This shows pragmatism. Those who know something knows how much test cases need to be really written to test all conditions and no good programmer ever does it; because many things are stable and work without extensive tests(at least most of the time)
Here is the same theme from the first modern/professional/industrial programmer who gave us structured programming and a lot of algorithms and so much more; This is from Edsger Dijkstra his 1972 Turing Award reception speech titled — The Humble Programmer.
How do we convince ourselves that this design is correct, i.e. that all these computations will display the desired properties? A naive answer to this question is “Well, try them all.”, but this answer is too naive, because even for a simple program on the fastest machine such an experiment is apt to take millions of years. So, exhaustive testing is absolutely out of the question. As a result, testing by random sampling is hopelessly inadequate as well, because even the most vigorous exercising possible will only cover a truly negligible fraction of the possible number of cases, and whole classes of in some sense critical cases can — and will! — be missed: only the most obvious blunders will show up. The first moral of this story is that program testing can be used very efficiently to show the presence of bugs, but never to show their absence ….
In the latter respect software seems to be different from many other products, where as a rule a higher quality implies a higher price. Those who want really reliable software will discover that they must find means of avoiding the majority of bugs to start with, and as a result the programming process will become cheaper**. If you want more effective programmers, you will discover that they should not waste their time debugging — they should not introduce the bugs to start with.**
https://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340.html
There are some people who say Unit Testing itself is a waste. I guess no Unit Test is real unit tests; you are already integrating with OS functions , Language libraries etc. Unit and Integration tests together make Testing During Development complete.
I can throw them the following Edsger Dijkstra’s quote also
Let me start with a well-established fact: by and large the programming community displays a very ambivalent attitude towards the problem of program correctness. A major part of the average programmer’s activity is devoted to debugging, and from this observation we may conclude that the correctness of his programs — or should we say: their patent incorrectness? — is for him a matter of considerable concern. I claim that a programmer has only done a decent job when his program is flawless and not when his program is functioning properly only most of the time. But I have had plenty of opportunity to observe that this suggestion is repulsive to many professional programmers: they object to it violently! Apparently, many programmers derive the major part of their intellectual satisfaction and professional excitement from not quite understanding what they are doing. In this streamlined age, one of our most under-nourished psychological needs is the craving for Black Magic, and apparently the automatic computer can satisfy this need for the professional software engineers, who are secretly enthralled by the gigantic risks they take in their daring irresponsibility. They revel in the puzzles posed by the task of debugging. They defend — by appealing to all sorts of supposed Laws of Nature — the right of existence of their program bugs, because they are so attached to them: without the bugs, they feel, programming would no longer be what is used to be! (In the latter feeling I think — if I may say so — that they are quite correct.)
When correctness concerns come as an afterthought and correctness proofs have to be given once the program is already completed, the programmer can indeed expect severe troubles. If, however, he adheres to the discipline to produce the correctness proofs as he programs along, he will produce program and proof with less effort than programming alone would have taken.
https://www.cs.utexas.edu/users/EWD/transcriptions/EWD02xx/EWD288.html
Or I could just tell them that they are right; Dijkstra was a man ahead of his time; what he meant was not just that we need to write tests during development or before coding etc. He was more into how a program can be formally verified.
However, we have not reached anywhere close to formal verification in 2018 and should stick with more coarse tools like testing. So testing during development is important for program correctness, and testing means all-encompassing, unit, integration and where relevant performance tests.
I will end with some pragmatism.
If I was a perfect coder; I will not write one line of tests. I know I am not perfect. I guess most programmers with one month or more production experience will know that. And I started writing tests and effective tests as my heart would jump at the midnight telephone ringing and I had to wake and go to the office at ungodly hours and code and correct at ungodly hours and I wanted a way to escape that, and writing tests during development helped me in that around 15 years back; and has helped me in catching a very bad bug in a program I wrote for a demo some two months back and all the time in between.
Am I a believer in Test First and Code later, that is Test First Programming as per Kent Beck? Yes and no; An analogy; though I have great respect for Jesus Christ, I am not going to do all that he has written. Love my neighbor! really my neighbor is the only person whom I don't share much love. I have great respect for all great programmers, but I will move out of my comfort zone and try some change, only if it hurts me so much if I do not change; not because Kent Beck wrote or some other expert wrote. I am like the overwhelming majority. I get hurt and I change; I know for sure product will get hurt if the new joinee’s don’t do this; so I will try all my best to force them to follow. Could be that there are some who are very very good that can churn out great code without a single test. If I know of someone like that, I won’t burn him/her in sake just because one did not follow the same religion. I long for such, to change the game, but till then it is TDD or Test During Development or
Code a Little ,Test a Little , Rest a Little,Maybe Think a Litte,And Goto Step 1 Again
The world need’s a better term than TDD.
*Code a Little Test a Little was suggested by my manager Kabilan T while we were in a meeting discussing TDD and nobody was getting what I was saying and we were all starting quarreling.
Related reading
One weird trick that will change the way you code forever: JavaScript TDD_'One weird trick' is a cheesy title, I know. Originally I was using it as a draft placeholder title for a joke. But the…_jrsinclair.com