TDD Is A BROKEN Practice

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I recently came across a critique of test room development that I've heard before and often but don't really understand I'll get stuff wrong all of the time which is exactly why I prefer test room development let me [Music] explain hi I'm Dave fary of continuous delivery welcome to my channel if you haven't been here before please do hit subscribe and if you enjoy the content here today hit like as well the critique that I came across was from ATM zenko here it is in it he says test room development implies writing tests before writing the code you write tests to describe the intention behind the system that you want to build how you expect it to behave tdd heavily implies that you should know how the system behaves before even implementing it you should know what you're doing most of the time you don't all the developers that I know don't know that ahead of time time I don't know that ahead of time so yeah okay I can agree with most of that I don't think that I agree with it in the way that artm meant though because he goes on to say I don't see test roomm development as a viable approach in fast evolving systems like the web well first I confess I found it slightly amusing that people writing web code nearly always assume that it's different and unique to writing any other non-web code it's not that I'm picking on web develop velers here because backend developers call me out because their code is special too so do developers of embedded code safety critical code package systems banking systems games and pretty much every other type of code that people write we're all special cases and so the recommendations of how to do a better job don't apply to us is seemingly what they're saying in the case of test room development there are examples of organizations doing it successfully for all of these different types of systems and many many more so maybe the special cases even if they are sometimes different aren't so special after all actually reading artm stuff there is a lot that I can agree with yes it is disappointed when PE people take the wrong message but describing testr development as pedantic constraints that no engineer can follow is simply and obviously factually incorrect because here I am a software developer who can use the so-called pedantic constraints to my advantage even for that parently tricky form of uh coding writing web apps to be fair I I do like have to give credit I do like a falsifiable statement and even more so when I get to falsify it I suppose it depends on the nature of web apps that we're talking about if your web app doesn't do very much and so it's mostly about playing with the Aesthetics and usability then yeah tdd is not lots of help for that part of the problem but my point is that I want to to test the other bits of the system the S the stuff that constructs the models that I may later display retrieves and stores the information interacts with the other parts of the system then I can keep those tests passing so that I can more freely change the parts of the code that that are focused on the pixel painting and more freely experiment with usability and nice look and feel let me pause there and say thank you to our sponsors we're extremely fortunate to be sponsored by equal experts trans fic and semor all of these companies offer products and services that are extremely well aligned with the topics that we discuss on this channel every week so if you're interested in excellence in continuous delivery and software engineering in general please do check out their links in the description below actually I saw artem's tweet because Kent Beck responded to it on Twitter and I saw Kent's response first which naturally I'd recommend Ken outlines his take on the importance of small steps with a simple example showing how we can make progress in unplanned incremental ways even when we don't have a grand master plan of the eventual destination I wanted to pick up on essentially the same point of view as Kent but from a slightly different angle this represents a common anti pattern that seems to me to be at the heart of rm's post that is Imagining the code that you will write when you write the test this is a very common mistake for tddb beginners um they're so used to diving directly into implementation that they can't prevent themselves from doing it even when they're being asked to start somewhere else in this case by writing a test so what they do is because they are being nagged by someone like me a trainer to start with a test they imagine the code that they will write and then they write the test to test that imagined code this has the same failure mode as writing your test after the code your test will be now be coupled to your implementation in this case an imaginary implementation what Kent is talking about in his post is very different to this this and does not rely on any perfect foresight at all tdd is a process of dividing the design of our software into a series of small actually Tiny Steps that incrementally evolve our software towards more effective higher quality Solutions this is the real trick the real skill of test room development to learn a more incremental approach to design so this is a million miles away from clever developers intuiting Perfect Solutions before they start I think that not only that this is a misre of the intent of test development but actually misses what I think of is probably the most important value that it brings test driven development creates a pressure on us to work in these small steps in my experience the more you practice test driven development the better you get at reactively steering the design design rather than attempting to intu it from the start in the long run this gives us a more effective more scalable higher quality approach to design overall giving us clear feedback on our design choices after each small step if you'd like to give test room development a try do check out my free tutorial or maybe even the paid for full more extensive tdd training course there's links to both of those in the description below test driven development is a more stable approach for lots of reasons but one the ideas that may seem subtle but is deeply important in terms of the stability and effectiveness of this approach is that it keeps our options more open after each small step which is why contrary to ATM's assertion and the doubts of the people that say that tdd isn't possible unless we have perfect foresight tdd works better than the Alternatives when exploring new ideas let's imagine three ways of Designing a system big upfront design which I'm pretty sure our att's not recommending an exploratory approach as he descri Des cries it and tdd or what I think of as exploratory with tests in big upfront design you think really hard and depending on the scale of the problem maybe you try to capture your design in some intermediate form so that you can remember all of the detail as you go through the process of thinking really hard and maybe you use these models then to explore and evaluate Your Design choices in the old days I used to do an awful lot of this kind of thing I was actually pretty good at it and built lots of systems this way but it's pretty limiting overall people working this way weren't stupid or naive though they tried to find ways to break the problem down into smaller steps and we ended up with modeling languages like uml and complex development process Frameworks like rational unified process that were meant to help but I think that the problems with this approach are pretty fundamental and broadly fall into two categories leaky abstractions and lack of real feedback the abstraction problem is evident our aim is to capture a design in reality the design of our code is written in code so however else we represent our code formal or not if we're doing that without the actual code there's going to be an abstraction lay on top of it all abstractions are leaky and diagramming techniques like uml are leaky in several problematic ways some ideas are much easier to express in code and some in diagrams so there can be a huge mismatch in the levels of abstraction between the diagram and the code either way around so something that looks complex in a diagram may actually be trivial in code try writing a for Loop in uml and something that is complex in the code may look easy in a diagram both of these are bad if we're trying to make choices about our designs based on pictures and in the absence of real code don't get me wrong there's nothing inherently evil in diagrams uml is a fine tool for conveying some ideas clearly but I think it's most effective when used at a very different level of abstraction to code and it's a big mistake to confuse the two it's too easy to express an idea in a diagram that is just plain stupid when it comes to the code the abstraction leaks the second problem with upfront design is how do we get feedback on the validity of our design there was a big push through the 1980s and '90s to try and formalize this with more formal diagramming techniques defining rules so that the tools could validate the diagrams this would be our feedback that checked our designs people were talking a lot in those days about model driven design assuming that we would raise the level of abstraction for for development by using diagrams and then generating the actual code from the pictures problem was this never really worked out very well it turns out that code AS text is remarkably good and flexible at representing ideas in this case a picture really isn't worth a thousand words code is often more precise and more concise in general software demands an annoyingly pedantic level of detail and precision and it turns out that text is better that than pictures pictures can help us navigate though but do a poor job of specifying things in sufficient detail to be reliably executable code is often more concise and more accurate representation of what it is that's really going on which means that when we come to realize a diagram based model of a design we'll often find mismatches at the level of the code so our design assumptions can easily be wrong until we get to the actual implementation the next level up from Big upfront design like this is 's suggestion of a more exploratory approach he describes it as prototype iterate test obviously I think that testing at the end like this is a big mistake it misses out on the large part of the value of test driven development which is the impact that test driven development has on the design of our code I believe that tdd forces us to be the first consumer of our code and so gives us the first and strongest feedback on the quality of our design choices as a result but as well as missing out on that so valuable feedback on our designs leaving the testing and until you're otherwise finished also misses out on the defensive value that the tests give you in test room development and and so making you more able to iterate how do you know that your iterations are still working uh and leading you in a sensible direction if you don't have those tests practically I don't see a lot of difference between rm's recommended approach and the more classical big upfront design because big upfront design never knows how bad your choices are until it's too late prototypes of fine they don't replace test room development though its job is something else entirely I think that artem's mistake here is another common though understandable one seeing test development as being primarily focused on testing after all test is right there in the name and I agree with him very strongly on the value of tests and automated tests in particular but I still think that it is the secondary value of test room development compared to the impact of tdvd on the development process overall and specifically in terms of driving better design choices and encouraging us to work in smaller steps so how does this compare to tdd well Kent Beck's point is very important one tdd encourages a more incremental more evolutionary approach to design development and testing we proceed in small steps and usually try to start with what seem like the easiest steps in my testm development training courses I often use a code exercise to add fractions to teach this incremental approach my first test is usually to begin with a test that adds the simplest possible kind of fraction that I can imagine a whole number something over one I don't need to have decided anything at all about my solution at this point it's obvious that this is a valid question that my code must one day be able to answer and I'm guessing that this is probably the simplest kind of addition for fractions that we'll ever need so the implementation will be simple but even if my guess is wrong at this point there's no real cost and my code and test will be really simple so I can change them easily playing with the design freely and once I've made my test pass I can still change the implementation detail as much as I like without changing the test all in the secure knowledge that I still need to add integer fractions and then I haven't broken anything yet so I'm picking a behavior that I'd like my code to exhibit bit but that won't be too challenging and won't demand that I write anything complicated to make it pass the subtlety that I think non-dd people often miss is that writing the test is about designing the external interface to your code the refactoring step is where we design the implementation detail not the red testing step this means that we can often play with our design before we have an implementation even I can and usually do do play with the interface of my code at this stage while it's what is probably the simplest state that it will ever be in a test calling a public API with as yet no working implementation beyond that it compiles allowing me to quickly and easily play with the public interface to my code from the perspective of a user of it I can use this to play with my design for essentially zero cost of change this is much easier than building some prototype of the whole thing even in this very first test I can be making decisions before I've decided How any of the implementation needs to work before I've even begun to think about the details of the problem that I'm solving I'm certainly going to need a fraction and so I can start writing that I can answer questions like how will my I represent fractions in my code how will I create them how will I compare them and so on I've started designing with the only overhead being two or three lines of test code and enough implementation free production code to represent the public interface to the code that I plan to write later I find this approach to exploration so much more effective than simply thinking hard and trying to solve the problems in my head once I have one test in place I can guess at the next small incremental step and write that if I don't like how I design looks as it evolves as I try to cope with incrementally more complicated versions of the problem then can go back a step or two now better informed and revisit my assumptions from earlier or still with tiny minute fragments of code no genius level foresight required anywhere here merely a slightly more organized slightly more disciplined slightly more incremental approach to design ultimately what this gives us is the freedom to design much bigger and more complex things because we're always building on something that we know works because we tried it relying on our tests to supplement our memories and our understanding of the code as the code gets bigger and more complex than we can easily hold in our heads this is a much more scalable approach thank you very much for watching if you enjoy our content here on the continuous delivery Channel please do consider supporting us by joining our patreon community thanks to our existing patrons for your ongoing support it's much appreciated and helps us to continue to make this material if you'd like to join check out the link in the description and look at all of the advantages that you can gain by being a patreon supporter thank you and bye-bye [Music]
Info
Channel: Continuous Delivery
Views: 29,415
Rating: undefined out of 5
Keywords: tdd, test driven development, how to use tdd, tdd tutorial, test driven development tutorial, what is tdd, tdd explained, is tdd dead, is tdd worth it, learn tdd, test driven development c#, test driven development python, test driven development java, software testing, automated testing, automated testing framework, software engineering, software development, kent beck, dave farley, continuous delivery, modern software engineering
Id: fPlBLlE8vOI
Channel Id: undefined
Length: 17min 13sec (1033 seconds)
Published: Wed May 01 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.