🚨 PRE-ORDER MY TDD COURSE AVAILABLE NOW! 🚨 ENROLL HERE 👉 bit.ly/3JB5smY Learn to write great tests, and how to use those tests to improve the design of your software: with step-by-step guidance and demos by Dave Farley, and practical exercises for you to learn TDD and BDD. Course Starts 20 April 2022.
@@mischock123 No, the course is mostly built around my collection of ideas to steer design from my book "Modern Software Engineering". The course talks about SOLID too, but the 5 principles mentioned here are my recommendations.
@@David-ic5nu These courses are based on a mix of video based training, recorded be me, Dave Farley, and with questions, references, a text based content and exercises. Occasionally we do run live, online courses too.
I simply LOVE your videos. But as a Software Engineer working for a startup here in Brazil, your courses are very expensive, they would eat almost a half of my monthly wage.
Took me years to understand TDD. I was always confused about multiple ways tests are used. To me, testing intuitively implied ensuring there are no hidden defects. Test null, test max_int, test negative numbers etc. Try to break design by corner cases etc. It took me much to realize that I want to test exactly the thing I'm trying to achieve, nothing more. If I'm thinking about the obvious case, I write test for the obvious case. If I'm thinking of some special case, I write test for that special case. Things I've not yet designed for are, on purpose, undefined behaviour. Ie. I'm using tests to design things, not to do QA. This difference is IMO something that's not often clear.
I've been practicing TDD (or BDD, rather) for about a year now and my mentality has been using it as a tool for QA first and design second. How do we ensure there are not hidden defects if we are only testing "exactly the thing I'm trying to achieve"?
@@aaronzhong I'm not sure really how to do QA, but it's IMO not a thing TDD is good at solving, or a thing it's for. You probably could have some separate test suite for QA made after-the-fact, but I am really not sure about best practices on managing that. But to me, I would probably do more expensive test suites like those hypothesis-type test suites trying to break your code, for QA, and rely on human QA people as well, and customer feedback. TDD on the other hand is to me solely a design tool, for capturing design intent. It needs to be extremely cheap to run tests, and extremely quick, so you can get immediate feedback on your actions. Writing said tests should not cause you to slow down writing production code, so attaching ambiguous QA targets to it is again imo bad, as you need to start taking time off to plan for QA, which imo requires a total context switch and way more time than typical "red" stage in red-green-refactor step. Resulting in poor QA while significantly slowing down development. I'd treat QA as a totally separate task, done after you have the code for QA. If QA then later reveals a problem, you fix it by writing a test that states problem doesn't exist, watch it fail, and go to fix it.
You spoke exactly what I thought. I tried TDD for a year and had many many failures. It was a hard lesson to learn how to use TDD especially if u don't have a tutor
Love it! I have been using TDD for about 6 years now, and the difference between code written with it and without it that I see in industry is night and day. Thanks for the great explanation for those curious about the benefits!
Write code that is (see: 8:01): 👉 Loosely Coupled 👉 Modular 👉 Cohesive 👉 Using Abstraction to Hide Information about implementation 👉 Good at Separation of Concerns
I've watched many, many videos and read several books on TDD to understand best practices. If I had to pick just one resource for someone just starting out on the TDD path to cover what TDD is and why you should use it, I would pick this one. You covered all the bases superbly.
The scales fell from my eyes with this video. I think I finally get it. And I love the little side-remark at the very end: "Oh, and as a nice side effect, we end up with some handy unit tests too" :mind-blown:
Dave, I think that people, who wanted to call TDD "Test Driven Design" had a better naming sense. It actually makes it easier to understand what you are talking about. And explains also, why I was always unsatisfied with TDD ignoring implementation detail.
I like the term 'Runnable Specification Driven Development'.. This was a very nice and clear talk and example. I am in the process of interviewing again, and I am on the lookout for teams that don't do CD and tdd. It's instrumental to hear the answers to "what is your CD goal, and where are you on that path?" I wish all the stuff you and jez wrote and you speak about was more widely (nay, universally) adopted. Thanks
Thanks. Have you seen this video on how to interview the companies that are recruiting you? It is meant to give some suggestions for exactly that problem: ruclips.net/video/2Afk9KVEgpE/видео.html
TDD forces you to think about why are you writing the code and it forces you to test the code. That is a very good thing. How many time did we write the code without understanding the requirements and pushed it to QA without testing to meet unrealistic deadline ? Then we prayed and hoped to live for another day.
2 года назад+13
Sorry for the correction, but.... assert "abc" and "bac" in anagrams.list_anagrams("cab") That line doesn't really assert than 'abc' is in the list. It assert that "abc" is truthy (always true) and that "bac" is in the list. You can change "abc" with "xyz" and the test will still pass. Great video anyway, as always.
I think testing is something that will be taken for granted in 5-10 years time. I work in the industry. I love writing tests. I've spoken to coworkers and internet strangers who contest the value of writing tests. I get confused why writing automated tests is controversial. Testing is great.
Unfortunately. I don't think there is any overlap in the venn diagram between those that understand the value of automated verification and those that find tdd controversial.
As a solo dev myself, I think you owe it to yourself to give it a go. I decided to try TDD in 2010 and I didn't find it easy at first, it probably took me at least a year before I was very comfortable with it and felt like I knew what I was doing. But, the feeling of confidence you get modifying a mature system and seeing that all your tests still pass - well that's addictive, but its something you really have to experience for yourself.
Great video. How do you use TDD when the code's job is to produce Gui only? When the things you want to be tested are: "I want the button to be red, the text to not overflow the screen in any given language translation, the pop up window not to hide the content completely, to look good with High DPI, to look good on mobile phones"?
Coding with intention. Especially the younger programmers fall in this trap(I can remember falling in this trap). Too often you start punching out code without knowing why or how but hoping you will stumble on the solution. TDD forces you to think what is the intention of the code and then capturing that intention in documentation(code).
I love watching these videos but one thing that irks me is that not a lot of content on TDD focuses specifically on UI development. I work primarily in the UI space and often applying these principles “feels” different than what was shown here. I’d love to see this channel do something UI specific.
The main reason is because the UI, in general, is hard to test. You could use a testing framework to test the user interface medium you're using (like HTML for example), but those are generally slow to execute. Another way you can do it is by using the Humble object pattern. You extract all of the interesting logic you want to test away from the view, and test it normally with unit tests. You then package the result into one or more data structures and pass it to the view. All the view has to do is take the data and put it on the screen. This way you can reduce the testing on the presentation side. This is preferable, because you don't want important business rules in the UI anyways. These are two popular approaches to solving this issue. Hope that helps.
I appreciate the reply and in all honesty that’s exactly the pattern I follow currently (working in the Angular space). I was just hoping I’d see Dave do some UI centric content at some point.
@@joepfohl5259 It its something that I have been thinking about doing a video on. The trick is to find something that is real enough to satisfy people, but simple enough to demonstrate the technique. I do have several attempts at this in several videos, here is one: ruclips.net/video/ESHn53myB88/видео.html I will keep trying.
There’s no such thing as tdd for UI other than “does it look like what it was supposed to look like”. (Hint: this isn’t an answerable question with code directly without feedback from users). Then everything underneath the UI is exactly the same as any other TDD. What actually matters on the visual aspect of the UI is the UX which comes from a mix of experience/intuition and A/B testing against real users.
After a successful day at work doing TDD, I come home to this video that just reinforces how awesome I was at work today. But in all seriousness, I swear by TDD and this video was on the money
TDD gives better design and also allows greater refactoring confidence. Adopting it is a no brainer. But it's so hard to leave our ego at the door and start with failing tests, straight to green and then refactor. We can often go straight to green. TDD requires a shift in process and thinking. Thanks for preaching the new testament of software engineering.
While I certainly agree in principle with regard to TDD as “Test Driven Design”, I think it’s important to note that in order to truly realize this the test environment must fully facilitate the ease of writing tests, perhaps even more so then the implementation environment itself. Reason being, a good design tends to reveal itself, but it could easily be overlooked due to test environment and implementation details derailing the effort.
Totally sold on TDD, but the biggest hurdle I see for its adoption is that TDD takes a culture change, if you were not doing it already. On personal projects, that is not an issue, but professionally chances are you are working on legacy code heavily in the maintenance phase, and you can consider yourself lucky if existent "after the fact" tests surpass 50% coverage... It would be great to see a video of how to introduce TDD on such a hostile, yet frequent, environment: - How to sell TDD to managers? - How to sell TDD to fellow engineers? How to sell it to juniors? And even harder, how to sell it to more senior engineers than yourself? - How to practically introduce TDD on a legacy code base in maintenance, which the best tests you can find, if any, are written "after the fact"? That would be a really good video to watch and help spread TDD.
This covers some of what you talk about: courses.cd.training/courses/refactoring-tutorial It is on my course site, so you need to sign-up, but this course is free.
No, I THANK YOU SO MUCH for bringing this invaluable skill to us and making it so easy to understand This video has easily become one of the best problem solving videos in my list
"If you write tests after the code, you only test the code that you wrote" and you end up missing out on everything else! This is sooo true, it is like living in a bubble
It may have been brought up, but didn't see it below: its been my experience that the value of having 'unit' tests is realized more AFTER the feature is done. I have been in several situations where refactoring things in a major way, perhaps implementing interfaces & abstract classes where much redundancy had grown over time... I was able to go about it very heavy handed and run the tests nearly constantly to either see if something got borked or changes had unforeseen consequences. When something DID get borked, the number of tests broken & where most for very little triage/debugging and I could focus on the end result. It also allowed me to have compileable project at all times in the event I needed to do it piecemeal. Lastly, having a large set of tests facilitates granular execution of Classes/Methods vs needing to run an entire project in a deployed environment to look at things. This isn't specific unto TDD, but is applicable.
Hi Dave, thank you for making all the videos on your channel. I agree with most what you say, and I am trying to incorporate a lot of things into my way of working. However, @18:35 I think this is not true. In my limited experience, TDD forces you to think and think hard about the problem. But knowing what is possible in the language you are implementing the solution in or design in general is very important. It for sure makes a difference that you are brilliant engineer and know what is good design and what is not, otherwise you wouldn't know all the questions that have to be asked and what are the tests to write. Eric Evans says that XP works best for developers with sharp design sense. Do you agree with that? And how do you obtain that sense?
I don't often disagree with Eric, but on this occasion, I am not sure that I do agree with that. In the general sense that "programming works better for devs with a strong design sense", then TDD does too, but I don't think that means that programmers with a weak design sense should ignore it. To be honest I doubt Eric meant that either. I think that TDD is a tool that importantly strengthens design skills. So it is even more important for programmers that aren't yet good at design.
Dear Dave, Thank you so much for creating this channel. I have learned a lot from you videos over the past months, and have been trying to put your ideas more and more into practice. However, our team deals with legacy code that does effectively the exact opposite of most of your ideas. Would you have any advice on how to proceed here? I see the bad, I see the wonderful world that could be, and I would love a roadmap to get there.
It is a bit more than a YT comment. I have some stuff on refactoring to get to a point where you can do TDD, it is on my courses site, but it is free: courses.cd.training/courses/refactoring-tutorial There is also a module on techniques to get to TDD in legacy code in my new training course, but I am afraid that is not free. In general my advice is use Approval testing to defend areas of the legacy code where you need to do work. Use that to refactor to improve the code (see the free course) to the point where you can do TDD. Aim to do TDD for any new code.
if you have an issue with the printing being done directly in this piece of code, should I assume that in your own code, you provide your own loggerservice/loggerfactory so as to be logger-implementation independent?
Yes, probably a good idea if you want to test log messages and it can make logging in your code simpler, depending on your logging library. Some logging libraries already provide a facade like this, so you don't need to write your own. Others are very simple so you don't need to write you own, unless you want to test it. But the code to add the indirection is trivial, and may reduce coupling.
Great video as always. But, there's a bug in `test_should_list_all_anagrams`? Did a quick check in a Python shell: % python3 Python 3.8.10 (default, Mar 15 2022, 12:22:08) [GCC 9.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> assert "foo" and "bar" in ["bar"] >>> assert "foo" and "baz" in ["bar"] Traceback (most recent call last): File "", line 1, in AssertionError Easy to overlook, just caught my eye.😀 Edit: the assert is actually only checking the `"bar" in ["bar"]`, the "foo" is truthy and is and-ed together with the result of the check after the and...
First, it isn’t mine, it was written by Steve Freeman and Nat Pryce. Next, yes, completely appropriate to my mind. The ideas it describes don’t change, so very relevant in my opinion.
I hope I didn't miss anything, but I think the solution here does miss a crucial test: It doesn't reject anagrams which are shorter than the word itself, only the ones with added letters. Otherwise a really awesome demo, I learned a lot!
You actually do need that test that rejects non-anagrams, because for example, "test" is not an anagram of "testword" but your program would think it is. Also I have a question - do we not need to have a test for the main "function" (code after if __name__ == "__main__") before writing it? Are we at that point done with TDD, main doesn't need to be written that way?
Yes to the reject non-anagrams, not to testing "main" IMO. I don't need 100% coverage for the sake of it, I may test "main" if it is complicated, but I am more likely to refactor my code to make main simpler.
Glad you liked it! Applying TDD to existing/legacy code is a whole other big topic! But I am producing a YT video on this in a couple of weeks. And I have a free Refactoring tutorial on my CD.Training site: courses.cd.training/manage/courses/1287815
Actually, there are companies that use red green refactor as time estimation method for features. In example: 1. how much time would it take to make the code that we are able to ship ? (green) 2. how much time would it take to make that code maintainable ? (refactor) And if the time between making code maintainable is equal or longer than creating a working code it makes sense to challenge the proposed solution.
To decouple his code, Dave often initializes his objects with functions, like with the display function. I am a bit uncomfortable with that, because it makes the code more dynamic and hinders the IDE functionality "go-to-method". While I see the benefits, it can create a "functionality-desert" where searching through the actual functionality keeps being behind yet another dynamically passed function. Any suggestion to easy my suspicion?
You can get exactly the same effect by creating an interface. I do it this way to try and demonstrate simplicity, and my choice is coloured by the nature of the problem, and the language that I am using. I'd usually create an interface in a statically typed language for example.
I recently heard TDD described as error prevention, whereas unit tests and any other type of testing as error detection. Additionally, TDD acts in the same way as double entry accounting - you have two chances to discover the code (or test) is wrong.
One thing I would love to see in a C++ test framework is a TODO system. Oftern, I have an idea for how the api should work, write down some lines of code that need an implementation. But it takes a while to get there.
i'm a bit confused about how you tested the display. the code doesn't test what is visible. you would need to capture the screen? why did you make that decision?
Well in the example, it is not my job to test that the Python library function "print" actually prints things. I can safely assume that. I am testing my code, not the whole world's. This is not me being lazy, and it was one of the pieces of advice in the original description by Kent Beck, test the code you are responsible for. You have to draw the line somewhere, and this is how TDDers usually draw it. Of course, if I was writing the display code, then I'd need to figure out how to test it, and pick the point at which to decide to stop. TDD is NOT about testing everything, it's about using tests to drive the design of YOUR CODE.
I like the video, and I learnt a lot from Continuous Delivery videos. I found one mistake in the tests. (I realized after commenting, that others already find it, but I have added the right test expression below.) "abc" and "bac" in anagrams.list_anagrams("cab") should be {"abc", "bac"}
Do you have any guidance on the following TDD scenario? Many of us practice proper TDD on our own projects and may have even come from companies that are fully dedicated to a functioning TDD environment. However, a new job may have placed us in companies with codebases containing giant impl classes containing thousands of lines each. Most of the methods are private and many times there is only one public interface into any of these classes. There may be (if you are lucky) a couple equally giant tests because, of course, the test scenarios must provide incredible amounts of valid data so the test will run. The mission of the new developer is to add some functionality to some inner private class which is basically "untouchable" and it would take a long time to scaffold properly before safe refactoring can occur. How should one approach such an ugly mess and "do the right thing?"
The key is refactoring of course, but also backed by approval (sometimes called characterisation) testing. I describe the here: courses.cd.training/courses/refactoring-tutorial
What a master class! really good. Thanks for your videos. I really appreciate them. I'm not able to afford the course, but I hope more TDD content here!
Does any one know any popular open source projects developed using TDD? I would to see an example that I could follow. Prefer in Java, Python or Javascript.
Dave, I’d really like to hear about you’re approach to go from “spike” to “balance”. I love TDD but when I have absolutely no clue how to implement something or the idea is evolving on the go, it can break the flow of creativity (TDD is not really the creative aspect, more the manifestation of ideas). So… spiking a project and than creating a new repository and re-writing it (thats how I have been doing it, if it ever made it out of the spike)? What do you suggest? Note for clarity: Spike = Messy, proof of concepts. Balance = Fully tested code.
TDD enables you to design your code without worrying about implementation. Instead you can focus on architecture and boundaries. Why are you throwing away and restarting every time? That code contains a lot of hard earned lessons.
@@sdporres Not really. TDD allows you to do that when you exactly know what the end result will be. But when you are i.e. iterating on the developer experience how an API should look and feel like, you’ll end up iterating over a large array of potential approaches of which most come up from the flow / learning of the previous approach. Exploration. And regarding throwing away code: Obviously the goal is to transfer / copy paste code from the spike into the balance repository. But that needs to be done actively so spike code is not “by default” in the implementation.
I think that Sergio has it right. TDD is not "this what to do when you know the answer", that suggests to me that you have too much of the internals of the design in mind. TDD is using the writing of the test to help you to make some decisions about what you'd like the external view of your code to be. How do expect people to use it? I find that particularly helpful when doing spikes.
@@ContinuousDelivery Ok. Here a concrete example since on a meta level it’s always “TDD is the best thing since sliced bread”. You have an existing system that has data (lets say a TypeScript node.js Project) and you want to use that data to create machine learning models (Python, Tensorflow and in between some data event layer). You need to add to the existing system now a new library you don’t fully know that allows you to create an API. Find a way that is working fine with the Python side (lots of try and error) while making sure that the API is convenient for use. This means on the fly you need to learn three things: (1) The capabilities and limitations of that new package you just added to the new system. (2) If it works, and if so, how it can uncover new limitations on i.e. the python side of things creating potential changes there. And (3) how to land at an acceptable middle ground between the two balancing limitations. That means you need to fiddle with three knobs constantly that are not independent from each other. Writing tests between every-time you make a change, does not only inhibit your learning rate but requires you to already know how to test aspects (limitations) that are not yet discovered yet. You’re fiddling with these three knobs to find them after all to come up with what this system will eventually be able to do. Learning at the same time how to use and test a library you eventually never use, breaks the inherently explorative aspects of software architecting. I hope that helps. PS: In general I believe the whole TDD scene is extremely short on concrete examples that address the “from idea to exploration then implementation” project life cycle. Which might be the reason that in reality coding practices from the exploration phase make it so far out to deployment phase - eventually having never any tests; like 9 out of 10 software projects we see in the wild. Thank you for your answer.
Story Short: Do a video on “Spike and Balance” ❤️ - how TDD might impact learning new technologies and what to watch out for. I.e. I often say: untested code is not allowed to have a P&L - not make money with. Everything else is fine. Because in the end: I’ve never seen any dev (also not at FANG) say: “okay, lets try reactjs for this. npm install react - now before we see if this is good for our use case, lets learn how to browser test this”. Love your content, greetings from Berlin
Finally I have been vindicated! This is how I have run test for more than 15 years. Over the last year I have lost 2 jobs (firings) because I use this method. I'm so happy I'm going to troll my previous managers. Oh hell I might send them a cake with butter cream icing with the words, "I was right!"
Function 'list_anagrams' may be writen as return list(filter(lambda anagram: (self._is_anagram(anagram, word)), self.word_list)). function _is_anagram could be static. in php return array_filter($this->wordList, fn($a)=>self::isAnagram($a, $word)) also real value of the class in the only function _is_anagram. So I would like to test this function _is_anagram, and it should be public and static. The filtering of array and printing of results should not be in the class at all.
I changed my mind: function which searches anagrams could be much more effective than just filtering a list of words, if we sort letters in each word alphabetically and put these words in a tree structure. So having function which searches anagrams could be also covered with a test.
I wish you could provide some examples of usage of TDD in a serverless functional paradigm for restful APIs. I have a get endpoint with no parameters. No entrance for variables. What is the point to create tdd for this function? We could get with some query atrings, dTe for example and for some reason the front end team will use a bolean value. For sure it will faill. Once it is corrected it will never fail again. Or should I create bad scenarios to test a scenario where a user will enter a bolean, an integer, a rwgular string etc etc.... in resume, what is the proupose of the test?
The purpose of the test is to let you see if the code does what you think it does, something useful. The test should look to assert some externally visible outcome. If there is no externally visible outcome, then presumably it doesn't do anything useful? I think that you maybe thinking about this the wrong way round. The aim of TDD isn't to start with a solution and say "how do I test this" it is to start thinking about the test as a design tool. You shape the code to make the test easy. That means that you design your solution to make behaviours more visible. The great thing about that, is that these things are also the properties that we value in great code. So the serverless aspect is just an invocation mechanism, so if that is just getting in the way for your tech, make it a dumb pass-through and start testing the thing it calls. What are the outcomes that you expect, figure out a way to make them visible and test them. I don't mean by breaking encapsulation, but by designing your code in a way that makes them naturally visible. Anyway I may have a go at a video on something like this, thanks for the suggestion.
I find that everyone likes to talk about TDD but very few, actually none I know of use it. Also while I think it is great, I'm not sure it is practical. Management don't care about it, you have to have a very good understanding of problem before you even start coding which is never the case, you have to constantly context switch, something devs hate, you can easily fall back and behind. I recently created a poll "Do you do TDD?". After 2 weeks, the poll closed and not one person voted.
Management is totally irrelevant. TDD is for developer. And yes, the point is, you want to understand what you're trying to do, writing code without this understanding is kinda insane, like, what do you expect to accomplish by that? And by context switch, what do you mean? It's constantly the exact same context, you define a goal, and achieve it in the context of your program.
@@gJonii I meant requirements and team understanding changes constantly. I agree with you on every point, it makes perfect sense as well. However, in reality, I saw very few teams doing it unfortunately. Main excuse is that it takes lots of time and confusing to get used to switch context btw writing code vs writing test all the time as you go through red, green, blue circle. My comment is not about whether TDD is good or bad. It was about practicality in a real world and acceptance in teams and organizations. I'm all about writing tests and if I would recommend how, if recommend TDD first. For the reasons above, I find that mostly teams either don't write tests (which means pretty much run away from that place) or teams write code, than tests. Very seldom, they write tests, than code. You say management is irrelevant. Sorry, but it is very relevant. If they tell you wet need this to finish in 2 days and it takes to write tests 2 days, then you usually end up in a non TDD solution. You either write tests later or not at all. For that reason, I say, in order to do TDD and experience is benefits, you have to be in a team that has very good understanding and is supportive, or you have to be an expert, so you are bringing it into the team instead of learning it within the team. And even if you bring it into the team as an expert, others still won't follow it because of the reasons above. Unless you are there only one working on code, it you have strict procedures and practices that are enforced and knowledgable people, good luck. Extreme programming, IMO, is the best practice for stable, self testing code and it uses TDD. However, and in my experience, very few organizations use it. If you are part of such a team, you are a lucky developer.
@@dinobulja One thing that jumped out to me: If you do TDD, you don't write tests for 2 days. You write a single test just long enough for that test to fail. Then you make it pass. If making a single failing test takes 2 days, something is terribly wrong.
@@gJonii lol. Funny. I question your expertise in this area. That or you don't read. Either way, I feel I failed to convey the point. To not go endlessly in circles, I'll just keep out of it.
There are some testimonials for each course on each course page and on the "About Page" for each course. Take a look here, and scroll down to the bottom. courses.cd.training/pages/about-tdd-bdd
The fundamental issue in teaching TDD is the mindset change, most Dev's taught either online or in schools are taught to focus on the code. It is a fundamental culture shift many are not happy with (rightly or wrongly). They are too focussed on the solution rather than the problem that is trying to be solved. Thinking you can fix everything by analysis and design up front. That is not to say that up front analysis is not required, it is, but the scope of the analysis needs to be focussed on the criteria you have specified here, rather than how each individual component is described with pre-conceived ideas about how everything must work in their mind's eye. This is not helped by "Grey beards" who have always worked a particular way and have zero interest in changing, or process frameworks (especially safety critical) that are stuck in the past and afflicted by the same closed mindset thought process. NOTE: Many elements of Safety Critical frameworks are necessary to ensure the reliability and integrity of the system, but there are also many elements that have failed to evolve with the changing environment.
I've worked out a deal with the t-shirt providers for a discount for CD viewers - bit.ly/3FVX3tP *Remember to use the discount code: ContinuousDelivery
I can see the benefits, but I can't help feeling that: Without TDD: 1 month writing code + 2 weeks debugging. With TDD: 1 month writing tests + 1 month writing code Can you show how and where these tests are invoked? Are the tests compiled into the release version, or are they in separate modules?
1 month writing code without tests = eternity of debugging. That is how all those legacy systems came to be and why they require hundreds of developers working on them and it seems like not enough (and it is not because no amount would be enough). Writing tests not only pays off long term but it pays off immediately because you usually spend very little to no time debugging. The tests are invokable in dev environment and are integral part of your CI. They are typically standalone executables or libraries to be run by test systems. Run by both developers as part of the development cycle and CI. They are usually not part of production releases although I have seen some tests being shipped for customers to run but those are not the kind you write as part of TDD.
@@gnarfgnarf4004 That is strawman argument. I simply answered your question but you clearly weren't after an answer. Tests help you produce better software faster and allow you to change your code later with confidence because the tests make sure it still works.
The actual design was done even before starting TDD, when the algorithm was conceived as 3-4 well defined steps. Such design decisions can be aided by tools such as CRC Cards, not TDD.
Let's be honest, if you wanna emphasize design then the name is terrible, it should be specification driven design and this can include multiple specification systems like all the kinds of tests that we all know, as type systems and other specification mechanisms as they are done in the aerospace industry that require a lot more rigor and safety because human lives are at stake.
the problem with TTD is that people who are still learning to code have no idea how to write proper code let alone proper unit tests. in fact, i would say most programmers don't write actual useful unit tests even after years of programming. this problem becomes compounded when you are learning a new framework or language. until you are an absolute expert in the framework and language you are working in, TTD just ends up making programming way less enjoyable and brittle in the sense that you will constantly be fixing your tests rather than building your program. sometimes its really best to just write code. you might not know exactly what you want to build until you start building it. explore your ideas. ya, in theory knowing exactly what the functionality will be before you start programming sounds great. but in reality, the way our code works transforms as we build our projects which ends up rendering a lot of the unit tests you wrote useless. and then you are forced to figure out if you actually broke things or if your unit tests were just dependent on some piece of functionality that is now changed. i personally think you should write unit tests only after you've written a complex piece of functionality that is key to your program functioning properly and that has a low probability of changing. then that test becomes useful when you are adding functionality to make sure that key piece of functionality is still functioning properly in conjunction with the new functionality. dont write useless tests. you will just end up creating way more work for urself.
Yes, TDD is not useful when you’re not sure where you’re going or how things work exactly and want to test things out. TDD is a tool in your toolbox, it’s almost never a good idea to use a single tool in every situation.
If the tests are brittle the problem is in not following TDD. It sounds to me like you are not fully understanding TDD and making tests without really comprehending their point. Like, you make it seem like you'd only write a test after when you know how you are going to implement the solution, which is exactly the opposite of how TDD says one should write code.
these videos are nice but he came up with the most childish and useless example. better to show from a perspective of frontend or backend developer in a real world application.
TDD is the best way for incompetent contractors to double their billable man hours and show off meaningless coverage metrics that have no bearing on the "quality" of anything. Those who can't, teach.
🚨 PRE-ORDER MY TDD COURSE AVAILABLE NOW! 🚨
ENROLL HERE 👉 bit.ly/3JB5smY
Learn to write great tests, and how to use those tests to improve the design of your software: with step-by-step guidance and demos by Dave Farley, and practical exercises for you to learn TDD and BDD. Course Starts 20 April 2022.
Five principles for code, are those the SOLID principles?
@@mischock123 No, the course is mostly built around my collection of ideas to steer design from my book "Modern Software Engineering". The course talks about SOLID too, but the 5 principles mentioned here are my recommendations.
are your courses taught live with real instructors, or are the courses pre-recorded?
@@David-ic5nu These courses are based on a mix of video based training, recorded be me, Dave Farley, and with questions, references, a text based content and exercises. Occasionally we do run live, online courses too.
I simply LOVE your videos. But as a Software Engineer working for a startup here in Brazil, your courses are very expensive, they would eat almost a half of my monthly wage.
Took me years to understand TDD. I was always confused about multiple ways tests are used. To me, testing intuitively implied ensuring there are no hidden defects. Test null, test max_int, test negative numbers etc. Try to break design by corner cases etc.
It took me much to realize that I want to test exactly the thing I'm trying to achieve, nothing more. If I'm thinking about the obvious case, I write test for the obvious case. If I'm thinking of some special case, I write test for that special case. Things I've not yet designed for are, on purpose, undefined behaviour. Ie. I'm using tests to design things, not to do QA.
This difference is IMO something that's not often clear.
I've been practicing TDD (or BDD, rather) for about a year now and my mentality has been using it as a tool for QA first and design second. How do we ensure there are not hidden defects if we are only testing "exactly the thing I'm trying to achieve"?
@@aaronzhong if you know in advance how to pass a test, why would your code be defective? 🤔
@@aaronzhong I'm not sure really how to do QA, but it's IMO not a thing TDD is good at solving, or a thing it's for. You probably could have some separate test suite for QA made after-the-fact, but I am really not sure about best practices on managing that.
But to me, I would probably do more expensive test suites like those hypothesis-type test suites trying to break your code, for QA, and rely on human QA people as well, and customer feedback.
TDD on the other hand is to me solely a design tool, for capturing design intent. It needs to be extremely cheap to run tests, and extremely quick, so you can get immediate feedback on your actions. Writing said tests should not cause you to slow down writing production code, so attaching ambiguous QA targets to it is again imo bad, as you need to start taking time off to plan for QA, which imo requires a total context switch and way more time than typical "red" stage in red-green-refactor step.
Resulting in poor QA while significantly slowing down development.
I'd treat QA as a totally separate task, done after you have the code for QA. If QA then later reveals a problem, you fix it by writing a test that states problem doesn't exist, watch it fail, and go to fix it.
You spoke exactly what I thought. I tried TDD for a year and had many many failures. It was a hard lesson to learn how to use TDD especially if u don't have a tutor
damn thank you I hadn't thought of it that way either
Love it! I have been using TDD for about 6 years now, and the difference between code written with it and without it that I see in industry is night and day. Thanks for the great explanation for those curious about the benefits!
Write code that is (see: 8:01):
👉 Loosely Coupled
👉 Modular
👉 Cohesive
👉 Using Abstraction to Hide Information about implementation
👉 Good at Separation of Concerns
CALMS 🙏😄
📍Cohesive implementation
📍Abstraction of data model
📍Loose coupling
📍Modular design
📍Separation of concern
I've watched many, many videos and read several books on TDD to understand best practices. If I had to pick just one resource for someone just starting out on the TDD path to cover what TDD is and why you should use it, I would pick this one. You covered all the bases superbly.
The scales fell from my eyes with this video. I think I finally get it.
And I love the little side-remark at the very end: "Oh, and as a nice side effect, we end up with some handy unit tests too" :mind-blown:
Thanks, I am pleased that you found it helpful.
Dave, I think that people, who wanted to call TDD "Test Driven Design" had a better naming sense. It actually makes it easier to understand what you are talking about. And explains also, why I was always unsatisfied with TDD ignoring implementation detail.
I like the term 'Runnable Specification Driven Development'..
This was a very nice and clear talk and example. I am in the process of interviewing again, and I am on the lookout for teams that don't do CD and tdd. It's instrumental to hear the answers to "what is your CD goal, and where are you on that path?"
I wish all the stuff you and jez wrote and you speak about was more widely (nay, universally) adopted.
Thanks
Thanks. Have you seen this video on how to interview the companies that are recruiting you? It is meant to give some suggestions for exactly that problem: ruclips.net/video/2Afk9KVEgpE/видео.html
@@ContinuousDelivery looks good, thank you.
TDD forces you to think about why are you writing the code and it forces you to test the code. That is a very good thing.
How many time did we write the code without understanding the requirements and pushed it to QA without testing to meet unrealistic deadline ?
Then we prayed and hoped to live for another day.
Sorry for the correction, but....
assert "abc" and "bac" in anagrams.list_anagrams("cab")
That line doesn't really assert than 'abc' is in the list. It assert that "abc" is truthy (always true) and that "bac" is in the list. You can change "abc" with "xyz" and the test will still pass.
Great video anyway, as always.
Oops! Thanks for pointing out the, now very obvious, mistake - Doh!
@@ContinuousDelivery you the man Dave 👍🏽
Noticed that too.
I think testing is something that will be taken for granted in 5-10 years time. I work in the industry. I love writing tests. I've spoken to coworkers and internet strangers who contest the value of writing tests. I get confused why writing automated tests is controversial.
Testing is great.
It's hard in existing systems without tests. And people that start projects only sometimes start with tests.
Unfortunately. I don't think there is any overlap in the venn diagram between those that understand the value of automated verification and those that find tdd controversial.
I've never been convinced about the value testing gives me as a solo dev so I've never used it, but this video has certainly made me reconsider it.
As a solo dev myself, I think you owe it to yourself to give it a go. I decided to try TDD in 2010 and I didn't find it easy at first, it probably took me at least a year before I was very comfortable with it and felt like I knew what I was doing. But, the feeling of confidence you get modifying a mature system and seeing that all your tests still pass - well that's addictive, but its something you really have to experience for yourself.
Great video. How do you use TDD when the code's job is to produce Gui only? When the things you want to be tested are: "I want the button to be red, the text to not overflow the screen in any given language translation, the pop up window not to hide the content completely, to look good with High DPI, to look good on mobile phones"?
Best explanation of TDD I've EVER seen!
Coding with intention. Especially the younger programmers fall in this trap(I can remember falling in this trap). Too often you start punching out code without knowing why or how but hoping you will stumble on the solution. TDD forces you to think what is the intention of the code and then capturing that intention in documentation(code).
I love watching these videos but one thing that irks me is that not a lot of content on TDD focuses specifically on UI development. I work primarily in the UI space and often applying these principles “feels” different than what was shown here. I’d love to see this channel do something UI specific.
The main reason is because the UI, in general, is hard to test. You could use a testing framework to test the user interface medium you're using (like HTML for example), but those are generally slow to execute.
Another way you can do it is by using the Humble object pattern. You extract all of the interesting logic you want to test away from the view, and test it normally with unit tests. You then package the result into one or more data structures and pass it to the view. All the view has to do is take the data and put it on the screen. This way you can reduce the testing on the presentation side. This is preferable, because you don't want important business rules in the UI anyways.
These are two popular approaches to solving this issue. Hope that helps.
I appreciate the reply and in all honesty that’s exactly the pattern I follow currently (working in the Angular space). I was just hoping I’d see Dave do some UI centric content at some point.
@@joepfohl5259 It its something that I have been thinking about doing a video on. The trick is to find something that is real enough to satisfy people, but simple enough to demonstrate the technique. I do have several attempts at this in several videos, here is one: ruclips.net/video/ESHn53myB88/видео.html
I will keep trying.
There’s no such thing as tdd for UI other than “does it look like what it was supposed to look like”. (Hint: this isn’t an answerable question with code directly without feedback from users). Then everything underneath the UI is exactly the same as any other TDD. What actually matters on the visual aspect of the UI is the UX which comes from a mix of experience/intuition and A/B testing against real users.
After a successful day at work doing TDD, I come home to this video that just reinforces how awesome I was at work today. But in all seriousness, I swear by TDD and this video was on the money
I'm gonna start watching this everyday to start my day. Thanks!
6:00 I think there's an error in the third test. What's written is equivalent to bool("abc") and bool("bac" in anagrams)
TDD gives better design and also allows greater refactoring confidence. Adopting it is a no brainer. But it's so hard to leave our ego at the door and start with failing tests, straight to green and then refactor. We can often go straight to green. TDD requires a shift in process and thinking. Thanks for preaching the new testament of software engineering.
While I certainly agree in principle with regard to TDD as “Test Driven Design”, I think it’s important to note that in order to truly realize this the test environment must fully facilitate the ease of writing tests, perhaps even more so then the implementation environment itself. Reason being, a good design tends to reveal itself, but it could easily be overlooked due to test environment and implementation details derailing the effort.
So true esp with hard-to-setup dependencies
Totally sold on TDD, but the biggest hurdle I see for its adoption is that TDD takes a culture change, if you were not doing it already.
On personal projects, that is not an issue, but professionally chances are you are working on legacy code heavily in the maintenance phase, and you can consider yourself lucky if existent "after the fact" tests surpass 50% coverage...
It would be great to see a video of how to introduce TDD on such a hostile, yet frequent, environment:
- How to sell TDD to managers?
- How to sell TDD to fellow engineers? How to sell it to juniors? And even harder, how to sell it to more senior engineers than yourself?
- How to practically introduce TDD on a legacy code base in maintenance, which the best tests you can find, if any, are written "after the fact"?
That would be a really good video to watch and help spread TDD.
This covers some of what you talk about: courses.cd.training/courses/refactoring-tutorial
It is on my course site, so you need to sign-up, but this course is free.
@@ContinuousDelivery Thanks a lot!
This is the best video of this channel so far! Well done!! Loved the example
No, I THANK YOU SO MUCH for bringing this invaluable skill to us and making it so easy to understand
This video has easily become one of the best problem solving videos in my list
"If you write tests after the code, you only test the code that you wrote" and you end up missing out on everything else!
This is sooo true, it is like living in a bubble
A great refresher video why TDD is so important.
Thank you :)
It may have been brought up, but didn't see it below: its been my experience that the value of having 'unit' tests is realized more AFTER the feature is done. I have been in several situations where refactoring things in a major way, perhaps implementing interfaces & abstract classes where much redundancy had grown over time... I was able to go about it very heavy handed and run the tests nearly constantly to either see if something got borked or changes had unforeseen consequences. When something DID get borked, the number of tests broken & where most for very little triage/debugging and I could focus on the end result. It also allowed me to have compileable project at all times in the event I needed to do it piecemeal. Lastly, having a large set of tests facilitates granular execution of Classes/Methods vs needing to run an entire project in a deployed environment to look at things. This isn't specific unto TDD, but is applicable.
Hi Dave, thank you for making all the videos on your channel. I agree with most what you say, and I am trying to incorporate a lot of things into my way of working. However, @18:35 I think this is not true. In my limited experience, TDD forces you to think and think hard about the problem. But knowing what is possible in the language you are implementing the solution in or design in general is very important. It for sure makes a difference that you are brilliant engineer and know what is good design and what is not, otherwise you wouldn't know all the questions that have to be asked and what are the tests to write. Eric Evans says that XP works best for developers with sharp design sense. Do you agree with that? And how do you obtain that sense?
I don't often disagree with Eric, but on this occasion, I am not sure that I do agree with that. In the general sense that "programming works better for devs with a strong design sense", then TDD does too, but I don't think that means that programmers with a weak design sense should ignore it.
To be honest I doubt Eric meant that either.
I think that TDD is a tool that importantly strengthens design skills. So it is even more important for programmers that aren't yet good at design.
Loved the video! I am at the beginning of my coding journey, and think this video will help me to take the right steps. ❤️
Can these same concepts be applied to procedural or structured programming?
Dear Dave,
Thank you so much for creating this channel. I have learned a lot from you videos over the past months, and have been trying to put your ideas more and more into practice. However, our team deals with legacy code that does effectively the exact opposite of most of your ideas. Would you have any advice on how to proceed here? I see the bad, I see the wonderful world that could be, and I would love a roadmap to get there.
It is a bit more than a YT comment. I have some stuff on refactoring to get to a point where you can do TDD, it is on my courses site, but it is free: courses.cd.training/courses/refactoring-tutorial
There is also a module on techniques to get to TDD in legacy code in my new training course, but I am afraid that is not free.
In general my advice is use Approval testing to defend areas of the legacy code where you need to do work. Use that to refactor to improve the code (see the free course) to the point where you can do TDD. Aim to do TDD for any new code.
Working Effectively With Legacy Code by Michael C. Feathers?
Great video, the example used here was perfect, I'll definitely use it in my Dojos to teach about TDD.
if you have an issue with the printing being done directly in this piece of code, should I assume that in your own code, you provide your own loggerservice/loggerfactory so as to be logger-implementation independent?
Yes, probably a good idea if you want to test log messages and it can make logging in your code simpler, depending on your logging library. Some logging libraries already provide a facade like this, so you don't need to write your own. Others are very simple so you don't need to write you own, unless you want to test it. But the code to add the indirection is trivial, and may reduce coupling.
Great video as always. But, there's a bug in `test_should_list_all_anagrams`?
Did a quick check in a Python shell:
% python3
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> assert "foo" and "bar" in ["bar"]
>>> assert "foo" and "baz" in ["bar"]
Traceback (most recent call last):
File "", line 1, in
AssertionError
Easy to overlook, just caught my eye.😀
Edit: the assert is actually only checking the `"bar" in ["bar"]`, the "foo" is truthy and is and-ed together with the result of the check after the and...
Yes, sorry, obvious now but I missed it at the time - Doh!
Quick question. Your Growing Object-Oriented Software, Guided by Tests book is not outdated?
Last edition is 2012.
First, it isn’t mine, it was written by Steve Freeman and Nat Pryce. Next, yes, completely appropriate to my mind. The ideas it describes don’t change, so very relevant in my opinion.
I hope I didn't miss anything, but I think the solution here does miss a crucial test: It doesn't reject anagrams which are shorter than the word itself, only the ones with added letters. Otherwise a really awesome demo, I learned a lot!
You actually do need that test that rejects non-anagrams, because for example, "test" is not an anagram of "testword" but your program would think it is. Also I have a question - do we not need to have a test for the main "function" (code after if __name__ == "__main__") before writing it? Are we at that point done with TDD, main doesn't need to be written that way?
Yes to the reject non-anagrams, not to testing "main" IMO. I don't need 100% coverage for the sake of it, I may test "main" if it is complicated, but I am more likely to refactor my code to make main simpler.
Very nice video! Keep making content like this. Anyway, I would like to ask how do you apply TDD to an existing code?
Glad you liked it! Applying TDD to existing/legacy code is a whole other big topic! But I am producing a YT video on this in a couple of weeks. And I have a free Refactoring tutorial on my CD.Training site: courses.cd.training/manage/courses/1287815
Actually, there are companies that use red green refactor as time estimation method for features.
In example:
1. how much time would it take to make the code that we are able to ship ? (green)
2. how much time would it take to make that code maintainable ? (refactor)
And if the time between making code maintainable is equal or longer than creating a working code it makes sense to challenge the proposed solution.
13:26
I think you have a bug in your test. `a and b in c` translates to `a and (b in c)` not `(a in c) and (b in c)`.
To decouple his code, Dave often initializes his objects with functions, like with the display function. I am a bit uncomfortable with that, because it makes the code more dynamic and hinders the IDE functionality "go-to-method". While I see the benefits, it can create a "functionality-desert" where searching through the actual functionality keeps being behind yet another dynamically passed function.
Any suggestion to easy my suspicion?
You can get exactly the same effect by creating an interface. I do it this way to try and demonstrate simplicity, and my choice is coloured by the nature of the problem, and the language that I am using. I'd usually create an interface in a statically typed language for example.
Quality codes are CALMS 🙏😄
📍Cohesive implementation
📍Abstraction of data model
📍Loose coupling
📍Modular design
📍Separation of concern
I recently heard TDD described as error prevention, whereas unit tests and any other type of testing as error detection.
Additionally, TDD acts in the same way as double entry accounting - you have two chances to discover the code (or test) is wrong.
5:49 No, I can't. Alas that code is a low-res blurry mess (checked playback settings; Auto 360p).
It is not in the original, it is 4k video and the code is readable. Try increasing your download resolution in your RUclips player.
Thanks you for this video! I'm waiting for next about London vs Classic School of Tdd:)
Nice referencing to the importance of knowing the question, not just the answer. Although the t-shirt gave it away already 😜
oh I have to ask, where do you get your t-shirts
usually from qwertee.com
@@ContinuousDelivery Thank you very much sir. Awesome content btw.
I am currently a fresher at my uni, learning c
i wanted know,what would be the books you would recommend to read right now?
help!!!!
amazon: C:The Complete Reference,4th Edition by Herbert Schildt
amazon: C How to Program 8th Edition by Paul Deitel (Author), Harvey Deitel (Author)
One thing I would love to see in a C++ test framework is a TODO system.
Oftern, I have an idea for how the api should work, write down some lines of code that need an implementation. But it takes a while to get there.
Why not do TDD?
How is this specific to C++? You can usually skip tests that fail due to lack of implementation. Or you can comment them out before you get to them.
i'm a bit confused about how you tested the display. the code doesn't test what is visible. you would need to capture the screen? why did you make that decision?
Well in the example, it is not my job to test that the Python library function "print" actually prints things. I can safely assume that. I am testing my code, not the whole world's.
This is not me being lazy, and it was one of the pieces of advice in the original description by Kent Beck, test the code you are responsible for.
You have to draw the line somewhere, and this is how TDDers usually draw it.
Of course, if I was writing the display code, then I'd need to figure out how to test it, and pick the point at which to decide to stop.
TDD is NOT about testing everything, it's about using tests to drive the design of YOUR CODE.
@@ContinuousDelivery oh i see. that seems fair. thanks
I like the video, and I learnt a lot from Continuous Delivery
videos.
I found one mistake in the tests. (I realized after commenting, that others already find it, but I have added the right test expression below.)
"abc" and "bac" in anagrams.list_anagrams("cab")
should be
{"abc", "bac"}
Do you have any guidance on the following TDD scenario? Many of us practice proper TDD on our own projects and may have even come from companies that are fully dedicated to a functioning TDD environment. However, a new job may have placed us in companies with codebases containing giant impl classes containing thousands of lines each. Most of the methods are private and many times there is only one public interface into any of these classes. There may be (if you are lucky) a couple equally giant tests because, of course, the test scenarios must provide incredible amounts of valid data so the test will run. The mission of the new developer is to add some functionality to some inner private class which is basically "untouchable" and it would take a long time to scaffold properly before safe refactoring can occur.
How should one approach such an ugly mess and "do the right thing?"
The key is refactoring of course, but also backed by approval (sometimes called characterisation) testing. I describe the here: courses.cd.training/courses/refactoring-tutorial
What a master class! really good. Thanks for your videos. I really appreciate them.
I'm not able to afford the course, but I hope more TDD content here!
Does any one know any popular open source projects developed using TDD? I would to see an example that I could follow. Prefer in Java, Python or Javascript.
Dave, I’d really like to hear about you’re approach to go from “spike” to “balance”. I love TDD but when I have absolutely no clue how to implement something or the idea is evolving on the go, it can break the flow of creativity (TDD is not really the creative aspect, more the manifestation of ideas). So… spiking a project and than creating a new repository and re-writing it (thats how I have been doing it, if it ever made it out of the spike)? What do you suggest? Note for clarity: Spike = Messy, proof of concepts. Balance = Fully tested code.
TDD enables you to design your code without worrying about implementation. Instead you can focus on architecture and boundaries.
Why are you throwing away and restarting every time? That code contains a lot of hard earned lessons.
@@sdporres Not really. TDD allows you to do that when you exactly know what the end result will be. But when you are i.e. iterating on the developer experience how an API should look and feel like, you’ll end up iterating over a large array of potential approaches of which most come up from the flow / learning of the previous approach. Exploration. And regarding throwing away code: Obviously the goal is to transfer / copy paste code from the spike into the balance repository. But that needs to be done actively so spike code is not “by default” in the implementation.
I think that Sergio has it right. TDD is not "this what to do when you know the answer", that suggests to me that you have too much of the internals of the design in mind. TDD is using the writing of the test to help you to make some decisions about what you'd like the external view of your code to be. How do expect people to use it?
I find that particularly helpful when doing spikes.
@@ContinuousDelivery Ok. Here a concrete example since on a meta level it’s always “TDD is the best thing since sliced bread”. You have an existing system that has data (lets say a TypeScript node.js Project) and you want to use that data to create machine learning models (Python, Tensorflow and in between some data event layer). You need to add to the existing system now a new library you don’t fully know that allows you to create an API. Find a way that is working fine with the Python side (lots of try and error) while making sure that the API is convenient for use.
This means on the fly you need to learn three things: (1) The capabilities and limitations of that new package you just added to the new system. (2) If it works, and if so, how it can uncover new limitations on i.e. the python side of things creating potential changes there. And (3) how to land at an acceptable middle ground between the two balancing limitations.
That means you need to fiddle with three knobs constantly that are not independent from each other. Writing tests between every-time you make a change, does not only inhibit your learning rate but requires you to already know how to test aspects (limitations) that are not yet discovered yet. You’re fiddling with these three knobs to find them after all to come up with what this system will eventually be able to do. Learning at the same time how to use and test a library you eventually never use, breaks the inherently explorative aspects of software architecting. I hope that helps.
PS: In general I believe the whole TDD scene is extremely short on concrete examples that address the “from idea to exploration then implementation” project life cycle. Which might be the reason that in reality coding practices from the exploration phase make it so far out to deployment phase - eventually having never any tests; like 9 out of 10 software projects we see in the wild. Thank you for your answer.
Story Short: Do a video on “Spike and Balance” ❤️ - how TDD might impact learning new technologies and what to watch out for. I.e. I often say: untested code is not allowed to have a P&L - not make money with. Everything else is fine. Because in the end: I’ve never seen any dev (also not at FANG) say: “okay, lets try reactjs for this. npm install react - now before we see if this is good for our use case, lets learn how to browser test this”. Love your content, greetings from Berlin
Brilliant! 👏👏👏
great video! thank you
Finally I have been vindicated! This is how I have run test for more than 15 years. Over the last year I have lost 2 jobs (firings) because I use this method. I'm so happy I'm going to troll my previous managers. Oh hell I might send them a cake with butter cream icing with the words, "I was right!"
Super pomogło mi !!
Function 'list_anagrams' may be writen as return list(filter(lambda anagram: (self._is_anagram(anagram, word)), self.word_list)).
function _is_anagram could be static.
in php
return array_filter($this->wordList, fn($a)=>self::isAnagram($a, $word))
also real value of the class in the only function _is_anagram.
So I would like to test this function _is_anagram, and it should be public and static.
The filtering of array and printing of results should not be in the class at all.
I changed my mind: function which searches anagrams could be much more effective than just filtering a list of words, if we sort letters in each word alphabetically and put these words in a tree structure. So having function which searches anagrams could be also covered with a test.
Thanks
I wish you could provide some examples of usage of TDD in a serverless functional paradigm for restful APIs. I have a get endpoint with no parameters. No entrance for variables. What is the point to create tdd for this function? We could get with some query atrings, dTe for example and for some reason the front end team will use a bolean value. For sure it will faill. Once it is corrected it will never fail again. Or should I create bad scenarios to test a scenario where a user will enter a bolean, an integer, a rwgular string etc etc.... in resume, what is the proupose of the test?
The purpose of the test is to let you see if the code does what you think it does, something useful. The test should look to assert some externally visible outcome. If there is no externally visible outcome, then presumably it doesn't do anything useful?
I think that you maybe thinking about this the wrong way round. The aim of TDD isn't to start with a solution and say "how do I test this" it is to start thinking about the test as a design tool. You shape the code to make the test easy. That means that you design your solution to make behaviours more visible. The great thing about that, is that these things are also the properties that we value in great code.
So the serverless aspect is just an invocation mechanism, so if that is just getting in the way for your tech, make it a dumb pass-through and start testing the thing it calls. What are the outcomes that you expect, figure out a way to make them visible and test them. I don't mean by breaking encapsulation, but by designing your code in a way that makes them naturally visible.
Anyway I may have a go at a video on something like this, thanks for the suggestion.
I find that everyone likes to talk about TDD but very few, actually none I know of use it.
Also while I think it is great, I'm not sure it is practical. Management don't care about it, you have to have a very good understanding of problem before you even start coding which is never the case, you have to constantly context switch, something devs hate, you can easily fall back and behind. I recently created a poll "Do you do TDD?". After 2 weeks, the poll closed and not one person voted.
Management is totally irrelevant. TDD is for developer. And yes, the point is, you want to understand what you're trying to do, writing code without this understanding is kinda insane, like, what do you expect to accomplish by that? And by context switch, what do you mean? It's constantly the exact same context, you define a goal, and achieve it in the context of your program.
@@gJonii I meant requirements and team understanding changes constantly.
I agree with you on every point, it makes perfect sense as well. However, in reality, I saw very few teams doing it unfortunately. Main excuse is that it takes lots of time and confusing to get used to switch context btw writing code vs writing test all the time as you go through red, green, blue circle.
My comment is not about whether TDD is good or bad. It was about practicality in a real world and acceptance in teams and organizations.
I'm all about writing tests and if I would recommend how, if recommend TDD first.
For the reasons above, I find that mostly teams either don't write tests (which means pretty much run away from that place) or teams write code, than tests. Very seldom, they write tests, than code.
You say management is irrelevant. Sorry, but it is very relevant. If they tell you wet need this to finish in 2 days and it takes to write tests 2 days, then you usually end up in a non TDD solution. You either write tests later or not at all.
For that reason, I say, in order to do TDD and experience is benefits, you have to be in a team that has very good understanding and is supportive, or you have to be an expert, so you are bringing it into the team instead of learning it within the team. And even if you bring it into the team as an expert, others still won't follow it because of the reasons above. Unless you are there only one working on code, it you have strict procedures and practices that are enforced and knowledgable people, good luck.
Extreme programming, IMO, is the best practice for stable, self testing code and it uses TDD. However, and in my experience, very few organizations use it. If you are part of such a team, you are a lucky developer.
@@dinobulja One thing that jumped out to me: If you do TDD, you don't write tests for 2 days. You write a single test just long enough for that test to fail. Then you make it pass. If making a single failing test takes 2 days, something is terribly wrong.
@@gJonii lol. Funny. I question your expertise in this area. That or you don't read. Either way, I feel I failed to convey the point.
To not go endlessly in circles, I'll just keep out of it.
Has anyone enrolled in Dave's course? I'd like to hear some reviews on it.
There are some testimonials for each course on each course page and on the "About Page" for each course. Take a look here, and scroll down to the bottom. courses.cd.training/pages/about-tdd-bdd
Nice easter egg🐰I checked my mail again!
The fundamental issue in teaching TDD is the mindset change, most Dev's taught either online or in schools are taught to focus on the code. It is a fundamental culture shift many are not happy with (rightly or wrongly).
They are too focussed on the solution rather than the problem that is trying to be solved. Thinking you can fix everything by analysis and design up front. That is not to say that up front analysis is not required, it is, but the scope of the analysis needs to be focussed on the criteria you have specified here, rather than how each individual component is described with pre-conceived ideas about how everything must work in their mind's eye.
This is not helped by "Grey beards" who have always worked a particular way and have zero interest in changing, or process frameworks (especially safety critical) that are stuck in the past and afflicted by the same closed mindset thought process.
NOTE: Many elements of Safety Critical frameworks are necessary to ensure the reliability and integrity of the system, but there are also many elements that have failed to evolve with the changing environment.
The question is famously 6*9.
Sorry, I love all the content but I still need to know where can I get those fantastic T-shirts!!!!
I have an announcement on that soon 🤫
I've worked out a deal with the t-shirt providers for a discount for CD viewers - bit.ly/3FVX3tP
*Remember to use the discount code: ContinuousDelivery
I can see the benefits, but I can't help feeling that:
Without TDD: 1 month writing code + 2 weeks debugging.
With TDD: 1 month writing tests + 1 month writing code
Can you show how and where these tests are invoked? Are the tests compiled into the release version, or are they in separate modules?
The big benefit should be that the tests are to catch any bugs that we wouldn't otherwise know about, if it weren't for those aforementioned tests.
1 month writing code without tests = eternity of debugging. That is how all those legacy systems came to be and why they require hundreds of developers working on them and it seems like not enough (and it is not because no amount would be enough). Writing tests not only pays off long term but it pays off immediately because you usually spend very little to no time debugging.
The tests are invokable in dev environment and are integral part of your CI. They are typically standalone executables or libraries to be run by test systems. Run by both developers as part of the development cycle and CI. They are usually not part of production releases although I have seen some tests being shipped for customers to run but those are not the kind you write as part of TDD.
@@Resurr3ction You presume that TDD will catch all the bugs? How naive...
@@gnarfgnarf4004 That is strawman argument. I simply answered your question but you clearly weren't after an answer. Tests help you produce better software faster and allow you to change your code later with confidence because the tests make sure it still works.
If I amplified my talent, I'd start moving backwards.
oh yes, TDD when the T stands for Types as in Hindly-Milner type system.
The actual design was done even before starting TDD, when the algorithm was conceived as 3-4 well defined steps. Such design decisions can be aided by tools such as CRC Cards, not TDD.
This is the NO SHIT, SHERLOCK! RUclips channel about software development.
Hmm interesting, the amount of time writing tests is the amount of time designing
Oh
Cool, 😋😋
Let's be honest, if you wanna emphasize design then the name is terrible, it should be specification driven design and this can include multiple specification systems like all the kinds of tests that we all know, as type systems and other specification mechanisms as they are done in the aerospace industry that require a lot more rigor and safety because human lives are at stake.
the problem with TTD is that people who are still learning to code have no idea how to write proper code let alone proper unit tests. in fact, i would say most programmers don't write actual useful unit tests even after years of programming. this problem becomes compounded when you are learning a new framework or language. until you are an absolute expert in the framework and language you are working in, TTD just ends up making programming way less enjoyable and brittle in the sense that you will constantly be fixing your tests rather than building your program.
sometimes its really best to just write code. you might not know exactly what you want to build until you start building it. explore your ideas. ya, in theory knowing exactly what the functionality will be before you start programming sounds great. but in reality, the way our code works transforms as we build our projects which ends up rendering a lot of the unit tests you wrote useless. and then you are forced to figure out if you actually broke things or if your unit tests were just dependent on some piece of functionality that is now changed.
i personally think you should write unit tests only after you've written a complex piece of functionality that is key to your program functioning properly and that has a low probability of changing. then that test becomes useful when you are adding functionality to make sure that key piece of functionality is still functioning properly in conjunction with the new functionality.
dont write useless tests. you will just end up creating way more work for urself.
Yes, TDD is not useful when you’re not sure where you’re going or how things work exactly and want to test things out. TDD is a tool in your toolbox, it’s almost never a good idea to use a single tool in every situation.
If the tests are brittle the problem is in not following TDD. It sounds to me like you are not fully understanding TDD and making tests without really comprehending their point.
Like, you make it seem like you'd only write a test after when you know how you are going to implement the solution, which is exactly the opposite of how TDD says one should write code.
these videos are nice but he came up with the most childish and useless example. better to show from a perspective of frontend or backend developer in a real world application.
TDD is the best way for incompetent contractors to double their billable man hours and show off meaningless coverage metrics that have no bearing on the "quality" of anything. Those who can't, teach.