Unit Testing Is The BARE MINIMUM

Ғылым және технология

Is TDD about more than just Unit Testing? What is a Unit Test, and how should we use unit tests? Unit tests evaluate small, isolated pieces of code. Test Driven Development is about driving the development process from the creation of tests, and not necessarily only unit tests. Generally, the output from TDD is a collection of unit tests, but if you only focus on the tests you are missing a large part of the value of TDD.
In this episode, Dave Farley, author of best-selling books “Continuous Delivery” and “Modern Software Engineering” and long-time practitioner and promoter of TDD explains why Unit testing alone is not enough.
-
⭐ PATREON:
Join the Continuous Delivery community and access extra perks & content!
JOIN HERE for as little as £2 ➡️ bit.ly/ContinuousDeliveryPatreon
-
👕 T-SHIRTS:
A fan of the T-shirts I wear in my videos? Grab your own, at reduced prices EXCLUSIVE TO CONTINUOUS DELIVERY FOLLOWERS! Get money off the already reasonably priced t-shirts!
🔗 Check out their collection HERE: bit.ly/3vTkWy3
🚨 DON'T FORGET TO USE THIS DISCOUNT CODE: ContinuousDelivery
-
BOOKS:
📖 Dave’s NEW BOOK "Modern Software Engineering" is available as paperback, or kindle here ➡️ amzn.to/3DwdwT3
and NOW as an AUDIOBOOK available on iTunes, Amazon and Audible.
📖 The original, award-winning "Continuous Delivery" book by Dave Farley and Jez Humble ➡️ amzn.to/2WxRYmx
📖 "Continuous Delivery Pipelines" by Dave Farley
Paperback ➡️ amzn.to/3gIULlA
ebook version ➡️ leanpub.com/cd-pipelines
NOTE: If you click on one of the Amazon Affiliate links and buy the book, Continuous Delivery Ltd. will get a small fee for the recommendation with NO increase in cost to you.
-
CHANNEL SPONSORS:
Equal Experts is a product software development consultancy with a network of over 1,000 experienced technology consultants globally. They increase the pace of innovation by using modern software engineering practices that embrace Continuous Delivery, Security, and Operability from the outset ➡️ bit.ly/3ASy8n0
Sleuth is the #1 most accurate and actionable DORA metrics tracker for improving engineering efficiency. Sleuth models your entire development cycle by integrating with the tools you already invest in. You get a full and accurate view of your deployments, see where true bottlenecks lie, and keep your team’s unique processes and workflows. With accurate data, Sleuth surfaces insights that your engineers can act on to improve - with real impact. ➡️ www.sleuth.io/
IcePanel is a collaborative diagramming tool to align software engineering and product teams on technical decisions across the business. Create an interactive map of your software systems and give your teams full context about how things work now and in the future. ➡️ u.icepanel.io/1f7b2db3
Tricentis is an AI-powered platform helping you to deliver digital innovation faster and with less risk by providing a fundamentally better approach to test automation. Discover the power of continuous testing with Tricentis. ➡️ bit.ly/TricentisCD
TransFICC provides low-latency connectivity, automated trading workflows and e-trading systems for Fixed Income and Derivatives. TransFICC resolves the issue of market fragmentation by providing banks and asset managers with a unified low-latency, robust and scalable API, which provides connectivity to multiple trading venues while supporting numerous complex workflows across asset classes such as Rates and Credit Bonds, Repos, Mortgage-Backed Securities and Interest Rate Swaps ➡️ transficc.com

Пікірлер: 198

  • @ContinuousDelivery
    @ContinuousDelivery11 ай бұрын

    Want to learn how to do TDD? I have a FREE tutorial, where you can practise the techniques along with me, here: courses.cd.training/courses/tdd-tutorial

  • @Veretax

    @Veretax

    11 ай бұрын

    oh I'm glad you pinned this I was like, I must be blind I didn't see it in the description.

  • @kB-hg2ci

    @kB-hg2ci

    11 ай бұрын

    Forbidden

  • @uome2k7
    @uome2k711 ай бұрын

    so many comments from people who forget TDD is not writing the test for the entire behavior ahead of time before the first line of code is written. You write a small test, write a few lines of code, update test(s), write few more lines of code, update tests(s), write few lines of code...repeating until you are done with your change. Nobody is expecting anyone to write an entire test suite before writing their first line of code.

  • @tongobong1

    @tongobong1

    7 ай бұрын

    Usually you write full test before the first line of production code and you don't change the test only production code when you write more full tests.

  • @Kitsune_Dev
    @Kitsune_Dev11 ай бұрын

    This is my summary of the video: Test Driven Development (TDD) vs. Unit Testing: The video emphasizes that TDD is not just about having a lot of tests. While TDD does result in a collection of unit tests, the real value of TDD lies in driving the development process from the creation of tests. This is different from unit testing where tests are written after the code has been developed. Writing Tests Before vs. After Code: Writing tests before the code ensures that the code is designed to be testable. This is because the tests are used to drive the code development, making it easy to test and use. On the other hand, writing tests after the code has been written makes the code less testable and the tests more complex and slower to run. Problems with Writing Tests After the Code: Tests written after the code are often larger, more complex, and slower. They are also more tightly coupled to the code, making it harder to add new features or change the implementation without breaking the tests. This can lead to projects grinding to a halt over time. Benefits of TDD: The goal of TDD is to produce high-quality software that allows faster and better development. TDD encourages good design practices, making the code more modular, cohesive, and abstracted with appropriate levels of coupling. These are the same properties that make code testable. Legacy Code and Test After Approach: In cases where you're dealing with legacy code that wasn't written with tests first, you might have to continue writing tests after the code. However, the video suggests starting to practice TDD for any new code straight away and gradually reshaping the software over time. Conclusion: The video concludes by stating that TDD is always preferred over unit tests written after the code. While unit tests written after the code might give temporary confidence early in the project's life, they can lead to problems in the long run. On the other hand, TDD leads to better design and high-quality software.

  • @powerswitchfailure
    @powerswitchfailure11 ай бұрын

    The hard part of TDD is making the design testable, not writing the tests. And, at least in my experience, writing the tests first doesn't make designing much easier. Early in my career, I consistently programmed test-first, but my tests were still complicated and tightly coupled to the code, because I didn't know how to design. Now, ten years later, I still write tests first some of the time-but my designs are testable even when I program test-after, because I'm thinking about how I'll test the code as I write it. I think the reason most teams don't do TDD boils down to a couple things: 1. They don't know how to design code to be testable. 2. When you show them how to design the code to be testable, they reject those design strategies as "too complicated" or "unnatural". They seem to have a deep-seated moral belief that code ought not to accommodate testing-after all, we write code to serve users, not to serve tests. If a team does not accept the idea that code should be designed to be testable, test-first programming will give them no benefit-so in a sense, they're right to reject it. (of course, I think they should design the code to be testable, so they can get the benefits of TDD!)

  • @llothar68

    @llothar68

    11 ай бұрын

    TDD is just stupid and anti human problem solving (which is done a lot of trial-and-error)

  • @vikingthedude

    @vikingthedude

    11 ай бұрын

    Very ey eell ll putu

  • @vikingthedude

    @vikingthedude

    11 ай бұрын

    Very well put

  • @vikingthedude

    @vikingthedude

    11 ай бұрын

    Ios 16 is BUGGY!

  • @chrvberg

    @chrvberg

    8 ай бұрын

    It may help to define the test as custumor zero 🙂

  • @pompiuses
    @pompiuses11 ай бұрын

    This was a great video. Hits the nail straight on the head. In just about every single project I've worked on the last 20 years the tests have been written after the production code by most developers, resulting in a highly coupled mess. In my experience most developers simply don't have the skills to do TDD properly. It's harder to learn than most think. In the microservices we're currently developing we have decided to only make black box acceptance tests against the api of the service and avoid unit tests as much as possible for this reason. This has worked great and the tests are now very loosely coupled to the code even when they're written afterwards. This works particulary well in microservices since they boot up in just a few seconds making the tests quick to run.

  • @yungifez

    @yungifez

    11 ай бұрын

    Yeah, my problem with tdd ( not a criticism of Tdd, just my day to day problem is coupling and mocking. How do I mock an entire database, or if not, how do I write tests for crud apps that focus on database operations mostly) Tdd is quite difficult, especially when using a framework and working on real life complex projects

  • @MrPatak007

    @MrPatak007

    11 ай бұрын

    @@yungifez Don't mock the database, create a whole real database when running tests. Just create a database locally through script or/and with docker.

  • @yungifez

    @yungifez

    11 ай бұрын

    @@MrPatak007 Yeah, i do that, and it slows my tests down dramatically Especially when doing tdd In my opinion. TDD must not be perfect in every system, depending on the margin of error allowable in that project and your future expectations of that future or even company ( that isn't to say that I write bad code ) but that I do not write tests before every single code change

  • @gradycdenton

    @gradycdenton

    11 ай бұрын

    @@yungifez I've struggled with this as well. Ultimately you have to do integration tests on code who's purpose is to integrate things, i.e. your backend and you're DB. The best you can do, IMO, is to write functions who's sole purpose is to execute queries and then call those functions in your API handlers. Then if your doing something like changing a validator or moving a route, but that change has nothing to do with the underlying DB or the query, you're free to mock the query function and just unit test the API code. It may seem like massive overkill to have a data persistence layer inbetween your API and the DB, but it makes future changes simpler. It also puts your biz logic in it's own layer, which is the toughest thing to test. That's where all the complexity should be. Keep your front end and your data access as simple as possible.

  • @yungifez

    @yungifez

    11 ай бұрын

    @gradycdenton thanks, I use laravel, which itself has an ORM, but when i tried mocking the database, i was in for a nasty surprise that sqlite had in store for me I ultimately just write tests that test the route works and the record reflects in the db I plan to change my strategy from today to test more individual parts of the code like validation etc asap

  • @peterlinddk
    @peterlinddk11 ай бұрын

    With the recent rise in AI tools to “write all the boring stuff”, I’ve seen a lot of even experienced developers choosing to just get all their tests written by an AI inspecting the code. I worry that his approach will do even more damage to the understanding of the DESIGN part of TDD, just like so many seems to have forgotten the MODELLING part of UML, and merely see it as documentation done after the program is written. It seems like he waterfall way of thinking is extremely hard to get rid of 😢

  • @llothar68

    @llothar68

    11 ай бұрын

    Well TDD is just as stupid as MODELING as a general purpose idea. Both failed terrible because both assume you do upfront what you are doing. And you don't. If you throw away lots of stuff it just doesn't matter to write tests or diagrams first. Executives and Method designers just do too little real code. Do you really think, guys like Dave or Uncle Bob really still do the hard job of coding new stuff?

  • @DagarCoH

    @DagarCoH

    11 ай бұрын

    ​​@@llothar68 You might be right about modeling (at least I struggle to do that in a harmonic way in my workflow, so instead I model for documentation after I can expect a module not to change any more), but not for TDD. The principle is not to write ALL your tests for all the functionality up front, but instead write one test for the function you are implementing next before you implement the function. In my experience this leads to less coupled code focused more on the essence of what it actually should do, and hence to code that is easy to adapt when requirements change. So if you have to throw away lits of stuff insteas of only small pieces, your tests, and code by extension, were a highly coupled mess to begin with.

  • @llothar68

    @llothar68

    11 ай бұрын

    @@DagarCoH And with some training you don't need this. Of course i write a few tests before, so i have something to run to develop my code interactively and learn the necessary APIs. But the purpose is never to do extending testing. In this step you need "asserts" and invariant checks. All what is known as DesignByContract. To get less coupling, test code is not necessary. It's just another design skill you have to apply, like performance and reliability and fault tolerance. It's exactly the same as UML, the idea of upper management that they can save money and help even untalented code monkeys to do the job. With this in mind AI scares me. Bad and miss understood AI

  • @JohnWilson-xl3rl

    @JohnWilson-xl3rl

    11 ай бұрын

    Properly experienced developers will get the AI to write the implementation not the tests.

  • @tongobong1

    @tongobong1

    7 ай бұрын

    @@llothar68 yes there is something fundamentally wrong with TDD or else more professional programmers would use it.

  • @mi98joni
    @mi98joni5 ай бұрын

    For me as a manager with no experience in the field, managing QA resources this channel is invaluable. Great work CD.

  • @andreasmuller8569
    @andreasmuller856911 ай бұрын

    I learned TDD, reading the 'right books' and much more from this channel - thanks sooo much. One thing not mentioned - guess even in your books - I experienced: There are situations desired behavior is not clear or at least does not fit into limited heads like mine. Performing the sequence of writing next test to challenge implementation more an write least amount of code to make test green serializes complex problems into small chunks. Found solutions I still doubt that it was me who wrote the code :)

  • @MMarbleroller
    @MMarbleroller10 ай бұрын

    I really like contract testing. I believe it is a very good thing. But I also believe it is important not to make the mistake of believing we can really anticipate everything by testing to the contract. We still run considerable risk from integration points that are affected by semantics not really described by the contract, but instead live in ways the data and state BEHIND the service contract may exhibit behaviors not anticipated or expected. I worked on a product which was using an identity stack/service that came from an entirely different department in the company. The API was a public API. The relationship between the product group I was in and this other department might as well have been between two different companies everything was so independent. At the time the product I worked on was developed, the was no way for a user to change their user principal name (UPN). For years, the UPN was something that would be the same once set for a given user. At some point, the group running the identity service added a feature that allowed users to change their UPN. There was no change to the contract we were consuming, no change to the public API. It turns out the product I was on had big nasty pile of bugs that derived from race conditions based on when the UPN was changed relative to prior usage history and background processes on the service. Data got out of sync, single users showed up as multiple users, user data became inaccessible, sites became unavailable. It was a nightmare, and it was complex. There was nothing about the contract that exposed this change in UPN might happen. It was more of a behind the contract semantic behavior. The service which handled user identity had no idea some consumer of their API was assuming the UPN would never change. We, as consumers of the API had no idea the UPN ever could change. This was an expensive bug for us. We lost some big customers. The damage done in the time it took us to address it probably cost us millions of dollars.

  • @rossbagley9015
    @rossbagley90155 ай бұрын

    I write tests and interfaces together at the start, then write implementations, occasionally updating tests and interfaces to get everything working well together.

  • @leerothman2715
    @leerothman271511 ай бұрын

    One other point worth mentioning is that if you write your test after you will never see the tests fail. If you don’t see it fail how can you be sure it’s correct? Been many times a unit test has passed before I’ve written the implementation due to not configuring a mock correctly.

  • @yungifez

    @yungifez

    11 ай бұрын

    This is so true I noticed writing tests after leads to a lot of false positives

  • @ardaonat1946

    @ardaonat1946

    10 ай бұрын

    Delete the code behaviour part that you are writings tests to, run the tests, see it failing, re-add the code, run the tests, see it passing.

  • @05xpeter
    @05xpeter11 ай бұрын

    I my experience the logic of making one test and then writing code to make that pass is what causes engineers to make tests very tied to the implementation. Since they are testing too small units and thereby implementation. Personally I prefer to write a set of tests first on a very high level maybe 5-10 tests which are the primary specs, then I start to code and write further tests as needed.

  • @gradycdenton

    @gradycdenton

    11 ай бұрын

    I was in the military so I think of strategy and tactics. Behavior driven development (BDD) is for strategy and TDD is for tactics. Your tactics should be driven by your strategy. It took me a while to get this until I started relating it to my past experiences outside of programming. Another concept that helped me is backwards planning, where you start with the end-state you wish to achieve and work back from there. For me, the thing you are asserting in your test is the "end state".

  • @andrealaforgia

    @andrealaforgia

    10 ай бұрын

    Unit testing means testing small units of *behaviour*, so the granular bits we develop driven by tests are granular behaviours. There is no reason why the tests your write before the code should in any way tied to implementation. Just write tests to assess granular behaviours.

  • @Satook
    @Satook11 ай бұрын

    This mirrors my recent experience jumping into a legacy codebase that had 8% test coverage. Black box, spec/scenario driven tests were invaluable in allowing a gradual refactoring to TDD, non-spaghetti code. And TDD was invaluable in the non-spaghetti part. Especially helpful as it stopped the temptation to mimic/reuse with the terrible design practices that resulted in the original spaghetti.

  • @JinnGuild
    @JinnGuild9 ай бұрын

    @Dave - Yes, yes and also yes. I especially want to "Yes" at your @16:53 -- Correct me if I'm wrong, but the pattern you gravitate toward is ISFC (Imperative Shell Functional Core). You refactor to allow for Dependency Injection, then you separate out the "Impure" stuff like hitting external SDKs or Databases, and you isolate the functional pieces to be as "Pure" as possible. Maybe you can't reach perfect ISFC, but that's essentially the direction you go in, would you agree? In my own consulting, I find it valuable to make it clear to people new to *Unit-Testing* TDD that code resulting from TDD are best observed as something like "Pure" functional methods. When your *Unit-Testing* TDD is finished, you then wrap the resulting great functional-esque code with an imperative shell that USES your logic, but composes it to and from impure calls. As my question to you moves toward a dark space that sounds like "TDD never touches a database", I also want to clarify on that. When I talk about TDD, I assume that people hear my words as talking about *Unit-Testing* prior to writing "Domain Logic". But I almost always clarify that TDD isn't only about that. The whole Shift-Left mentality comes in to play even as far as to say SDET teams (or their ilk) should be writing tests against APIs as soon as the contracts are decided. Possibly even finishing before dev work starts, but definitely finishing before dev work ends. TDD absolutely includes testing "integration" and "acceptance". Though generally when our audience is the frequent dev working on the middle tier, TDD is taken to mean Unit Testing before writing Domain code. Thoughts?

  • @tongobong1
    @tongobong17 ай бұрын

    Great explanation of why we should do TDD.

  • @Gary693
    @Gary69311 ай бұрын

    I just wrote a test for a function after I wrote the function. The function was working, but I needed to amend it to cater for different criteria. It was a lengthy process to test the function within the context of the whole application so I decided to try Visual Studio's unit testing feature to help speed up development. It helped immensely. So I think writing unit tests after code can still be useful. The unit test ran my function thousands of times with random data which would just not be possible testing the application as a whole as this would typically take place over a week.

  • @tongobong1

    @tongobong1

    7 ай бұрын

    You just wrote a bad unit test. Good unit test has well defined inputs and outputs.

  • @orlovskyconsultinggbr2849
    @orlovskyconsultinggbr284911 ай бұрын

    I agree with statements, making test easy is very important. Hard to read code , now finally we have ChatGpt which can describe what the hard parts doing and then we can refactor and write test which would test the right specs.

  • @kayakMike1000
    @kayakMike100010 ай бұрын

    Smoke test, functional tests, soak test, integration tests, fuzz tests, etc etc. Automate them all!

  • @radekcrlik5060
    @radekcrlik506011 ай бұрын

    Perfect timing. Exactly in time where folks on the project I am working on started removing unit tests and replacing them with integration tests that do multiple steps and assert mutliple things. Replacing one problem we had with another. I agree with @pompiuses below. Testing is a skill and needs to be learnt. Especially juniors lack the knowledge and struggle with simple concepts. For example, they struggle with using mocks. But I am not sure if it's a good excuse for cutting corners. It is a skill and skills can be learnt. People just need to be willing to invest some time and learn it. More or less I agree with points said in the video. It would be great to have some materials or examples how to write good tests so it can be shared with others. I will check out the course :)

  • @tongobong1

    @tongobong1

    7 ай бұрын

    Writing mocks is usually bad except when mocking resources that are outside the process because there is no other way to create a unit tests for code that accesses those resources. I guess they removed unit tests that were full of mocks - the terrible unit tests. Unit test can have more than one assert but it should never have multiple steps because in that case it is not a unit test but contains more tests inside one test.

  • @benlaceyseniordev
    @benlaceyseniordev5 ай бұрын

    I cannot agree more with everything you covered. Very detailed and good examples of test before Vs test after. How would you approach a code base with no unit tests? Where would you begin to make changes?

  • @andrewshawcare
    @andrewshawcare11 ай бұрын

    I think one of the problems with explaining TDD is when to move up the hierarchy of tests. There's a few camps in different areas of TDD land. Classicists and mockists have views about what to test, there's views about testing before or after writing code, and also what level tests should be written (unit, functional, e2e, etc.). For the latter, there's lots of views on the distinction between the test hierarchies (and pyramids/trophies to aid) but I'm not sure I've seen discussion about how to decide what level a new test should operate at. It's good to show when a... "hierarchy violation" has occurred (an integration test when a unit test should suffice), but when is an integration test justified? How would you know, and at what stage of TDD would you know it?

  • @tongobong1

    @tongobong1

    7 ай бұрын

    Mockists are writting terrible unit tests because they are hard to read and understand and are coupled with implementation. Use integration tests whenever your program accesses resources outside the current process like DB, filesystem, web... You can write integration test first and then unit test from that integration by mocking the access to outside resources.

  • @Veretax
    @Veretax11 ай бұрын

    On the one that calls a server, I get you are using it as an example of a test after implementd, but it also isn't even a UNIT test. By definition that would be an integration test. But the reason you want to right Unit tests first, is because you can build the scaffolding of unit tests as you write bits of code, and are less likely to test too much at once.

  • @algernon69
    @algernon6911 ай бұрын

    Dave, excellent content. Could you make a video with some TDD tips with mocks? I find it hard to think of mocks without having the code first.

  • @BusyAnt1234

    @BusyAnt1234

    11 ай бұрын

    This. I believe "don't use mocks" is the answer, as presented in another video. Nevertheless, I'd also greatly appreciate some practical advice on more than just a helloworld app or a 2-line method 🙏

  • @algernon69

    @algernon69

    11 ай бұрын

    I don't remember any "don't use mocks". I do remember Dave suggesting to avoid mocking third party libraries (altho I am still not sold on that). But how do you write unit tests in isolation without mocking?

  • @BusyAnt1234

    @BusyAnt1234

    11 ай бұрын

    @@algernon69 reducing the number of dependencies of each class and using fakes I guess. If you consequently apply dependency inversion, this should be possible. But don't quote me on that, as you see I am also struggling :D

  • @algernon69

    @algernon69

    11 ай бұрын

    @@BusyAnt1234 no problem, but what do you mean with "use fakes"? What's the difference between mock and fake? 🙃

  • @trignals

    @trignals

    11 ай бұрын

    @algernon69 this video should help: m.kzread.info/dash/bejne/i4Vt086coZm_qco.html That chanel also has an intro to TDD (talk playlist) which lists several resources at the end. Personally I followed James Shore's Let's Play TDD series.

  • @faraonch
    @faraonch11 ай бұрын

    @ContiniousDelivery How do you test a SaaS and Frontend heavy project? Meaning a lot of UI and Markup? Also together with CI?

  • @wwkw4992
    @wwkw499211 ай бұрын

    Excellent video which focuses on the very important aspects of św engineering. Just one comment from my side: to be able to make tests first, or at least in parallel with the implementation we nieed to have a common base. You named it design. I'm goinin to use a bit stronger word- requirements. No requirements -> no valuable tests.

  • @tongobong1

    @tongobong1

    7 ай бұрын

    Great point! Also if there is a list of well defined requirements for legacy code without tests we can make good tests for that code too no matter how messy it is provided we can change the design so much that we can get the correct feedback from the system.

  • @manishm9478
    @manishm947811 ай бұрын

    I agree tests should be written first, but there's a gap in the arguments presented - especially with the example shown: - unit tests (like the example) WILL be tightly coupled to the code under test, unless you use behaviour tests instead - behaviour tests are extremely complicated and expensive to set up and use (to use the example, we'd need to format it with the given-when-then style syntax: given the website when a localhost url is used then an exception is thrown) - complicated tests mean they are written less frequently, harder to understand and increased to do more things. As Dave correctly points out - now these behaviour tests start to compete with acceptance tests, except they may still be using mocked services or an in-memory database so they're not the same - programmers get such a headache working with them that they give up and just write the code, then find a way to wrangle a test to get their PR approved. My point is, write tests first and don't worry about trying to decouple them from the code under test. As Dave says, the quality will be much higher overall. If tests fail due to a new code change, great! Just go and fix them because now the dependencies are clear and being lightweight tests the changes should be easy!

  • @ApprendreSansNecessite

    @ApprendreSansNecessite

    11 ай бұрын

    I have a minor vocabulary disagreement: any test is a behaviour test. What else would we be testing? We even try our best to only couple our tests with the behaviour, so that refactoring is safer. Acceptance tests are the tests that matter to the business, they ensure that you are building the right thing, while other tests matter to the developers and ensure that your code is right. I find this distinction clear enough. An acceptance test can test any level of collaboration, from unit to end to end. The form "given when then" is used in acceptance tests (especially in gherkin) but nothing stops you from using this form in the description of a, technical, unit test. I find it helpful when dealing with edge cases for example because the state in which they occur and the behaviour that needs testing can be very precise and this structure adds familiarity and clarity.

  • @someoneelse5005

    @someoneelse5005

    11 ай бұрын

    The idea of unit testing that is employed in for instance Java programming is very misguided. Unit is not a single method in a single class. It could as well be a single unit of useful functionality that is always used in a particular context. There is no need to test so granularity. If your test tests your implementation rather than behavior it is in almost 100% cases a wrong approach to begin with!

  • @ApprendreSansNecessite

    @ApprendreSansNecessite

    11 ай бұрын

    @@someoneelse5005 I was not a fan of frameworks already but I noticed that some of them were dictating the unit under test as well. However I find it interesting that depending on the language the testing practices differ. For example, in Rust you are encouraged to test the internals.

  • @someoneelse5005

    @someoneelse5005

    11 ай бұрын

    @@ApprendreSansNecessite It makes sense, rust is a performance and stability critical systems language. It makes no sense to do the same thing in Java when the real impl of low level concepts is hodden in JVM.

  • @waffle8364
    @waffle83647 ай бұрын

    what about doing spikes? Where you are unsure of the estimates?

  • @JB__
    @JB__2 ай бұрын

    At risk of pointing out the obvious, the one thing that test-later has over TDD is that something gets shipped faster. Fast but scrappy has its place but it comes with a cost. And the core problem technical folks have is convincing others that this speed is a false economy that will ultimately limit the value of the software by miring teams in a swamp of buggy spaghetti code.

  • @jimhumelsine9187
    @jimhumelsine918711 ай бұрын

    Yes, yes, yes, yes, yes and yes!

  • @sneibarg
    @sneibarg11 ай бұрын

    I'm trying to advocate for TDD at my employer as a first principle of their philosophy. I tried to muck through 4 figures of tests that were probably all written after the application code. Massively difficult to decouple among this company's culture.

  • @gammalgris2497
    @gammalgris249711 ай бұрын

    I guess I still need some more practice regarding TDD. My usual approach is to start with something like an interface to describe the outside view/ behaviour of a data type/ class/ module/ component. Then it's easier for me to do the tests. At this point it's easy to change things if things are missing or not really working out. In general the first tries and drafts are not good. After the tests and code exist, how do you still keep up the notion of doing tests first and then code? The lazy way is to change the code first.

  • @tylerkropp4380

    @tylerkropp4380

    11 ай бұрын

    Writing the test first guarantees you wrote the test. Technically, in an established codebase, adding one thing test-after is totally feasible and doesn't impact the architecture. But sometimes you forget to write the test, particularly if you were working on something else entirely and only noticed the bug. If you forget the test, then someone may do a refactor of the internal logic and not include the bug fix, because it's not a requirement of the code module (as defined by the tests). Practically, if you use TDD habitually, then it won't be a very serious temptation. And if you are still learning, use it as an exercise to practice TDD.

  • @Flamechr
    @Flamechr11 ай бұрын

    Can you write a test by the story ? If not fix that first then write the test then the code.

  • @elfnecromancer
    @elfnecromancer11 ай бұрын

    How do you think this applies when writing both acceptance and unit tests? Should we write both before writing the application code? How would that work in TDD context? red/green/refactor explanations never mention that there could be a set of two reds and greens.

  • @JohnWilson-xl3rl

    @JohnWilson-xl3rl

    11 ай бұрын

    Look up outside-in double loop TDD

  • @ApprendreSansNecessite
    @ApprendreSansNecessite11 ай бұрын

    The debates I have are not about testing first or testing later, they are about not writing unit tests at all, they are about TDD driving the design towards complexity because it requires indirections. Better have a simpler design and a powerful end to end testing library. It's what I hear all the time and it's hard to argue against that, because people make it sound like the pragmatic approach when it really sounds like the careless approach to me. But if there was a right way and a wrong way, there wouldn't be debates. I guess they are 2 schools of thought. Sadly I think the "careless" school of thought is the dominant one. When looking for missions I read a lot of "working on improving our test coverage and stack" which means they care a lot about the tools they use, they did not write tests first, and the code is probably hard to test

  • @logiciananimal
    @logiciananimal11 ай бұрын

    Does anyone know if the various testing approaches have been "put through the wringer" by psychologists who know the literature on confirmation bias? I have long wondered which way the CB "flows" in software testing. Since CB is one of the cognitive weaknesses testing is supposed to help overcome, I figure that "test the testing" (or testers) might be a good idea. I know it does not appear in any detail in a recent book on the psychology of programming.

  • @uome2k7

    @uome2k7

    11 ай бұрын

    Writing tests for code you already have would be more biased to that code than testing for the requirement and then coding for that test. This is because writing the tests after the code gets you to guess the requirements based on what the code is doing. You have no idea if the code is doing what its supposed to be doing, you only know what it does.

  • @Artoooooor
    @Artoooooor11 ай бұрын

    I understand importance of TDD. However I struggle to implement it in lower level code. For example - PPU in NES emulator. It contains many moving parts and the output (pixel colour) appears many cycles after we make input (VRAM value or even current value of pointer to VRAM). Pipeline is quite long (16 cycles if I remember correctly). Do you have any experience in this kind of programs using TDD?

  • @tylerkropp4380

    @tylerkropp4380

    11 ай бұрын

    At a certain point, we can no longer test properly - dealing with hardware, graphics, operating system calls, etc. But it sounds like in your case, maybe you should stub out the execution of the emulator in order to test the PPU in isolation. As you say, it's very hard to test both a PPU and an emulator at once. You can have those unit tests plus the (few) integration tests that include the emulator, which would be much more basic, something like checking after X cycles that the buffer looks how you expect.

  • @Artoooooor

    @Artoooooor

    11 ай бұрын

    @@tylerkropp4380 Thanks for suggestions. Generally - I do test PPU in isolation. However I ended up with checking internal state of the pipeline, which tied tests to implementation. Now I think splitting it up to two parts - one handling memory-mapped IO and one just rendering could make it easier to test. So I can run something like: setCycle(FIRST_RENDER_CYCLE-1); setPalette(0, 255); wait(1); assertEq(screen[0],255); Thanks.

  • @NicodemusT
    @NicodemusT11 ай бұрын

    This carries with my understanding of best practices as well. Although, I wish there was some content out there discussing how small agencies deal with developing software w/ TDD. In a software business, applying TDD to everything is something you can sell internally - as everyone stands to benefit from it. In agency settings where every client is different, it is more arduous to sell TDD in smaller-scale systems, where budget and timing come into play. I know developers will argue "well, don't work with them if they don't have the budget for TDD", but when clients budget for software development, they aren't privy to everything you are, and so they do enter RFPs, quote farming a lot of the time without consideration for TDD. We can argue that these clients are left behind, but there's money left on the table - and I personally prefer working on smaller teams, with smaller clients and various projects that all have different degrees of involvement from the client. TDD just doesn't practically fit in a lot of agency work - and I think it should be talked about, so that perhaps agency-friendly TDD can be developed. As it stands, the 1-3 developer shop, working on a mix of projects represent a decent chunk of the workforce, but most of that work is being done without TDD. People say they do. They don't. I've worked at many agencies, and even when they say they do TDD, it's not anywhere near even 50% coverage.

  • @sashbot9707

    @sashbot9707

    11 ай бұрын

    I just don't mention it. No one complained yet.

  • @NicodemusT

    @NicodemusT

    11 ай бұрын

    @@sashbot9707 Sure, but if the intent is to have everyone employ TDD, the conversation should also include the spectrum of employment where it is the MOST difficult to implement. Working at a software/SaSS - it is much easier to preach this opinion - that "TDD is an absolute must!" I 'm not saying TDD is bad, just that its additional work does not often result in a discernible difference in time loss vs. no TDD and fixing bugs as they happen. When I have had the time to implement TDD, I have enjoyed it - but when projects are a revolving door, the focus and budget required is much harder to acquire consistently.

  • @trignals

    @trignals

    11 ай бұрын

    @NickTomkin I don't understand the problem. If TDD is not the fastest way for you to deliver what the customer wants to pay for why would you do it? If TDD is the fastest way to deliver what the customer wants why do they need to know about your approch? Looking for budget for TDD means it doesn't pay for itself. Maybe you mean the pain avoided by TDD happens after your contract is completed, i.e. you are delivering higher quality?

  • @NicodemusT

    @NicodemusT

    11 ай бұрын

    @@trignals There isn't a problem, per se. It's more of the "TDD is a must" meets "reality"

  • @manishm9478

    @manishm9478

    11 ай бұрын

    @@NicodemusT You raise a valid point. The context in which the code is written is important to consider. Is your agency writing new code or modifying existing? I think TDD works best with new code and shouldn't increase the overall time to write code for an experienced developer. I've been working in enterprise dev lately, which is mostly modifying existing stuff, and I can easily spend 5x more time writing tests than making the change. In such a situation, but on a small scale or short lived project, i'd suggest just writing some high level acceptance tests + manual testing.

  • @TheChexmo
    @TheChexmo5 ай бұрын

    is there any video(s) that explain how to apply tdd in real life? most of what i found (including that video of Continuous Delivery) is on a scratch project, very far from real life complexities

  • @pixelslate9979
    @pixelslate997910 ай бұрын

    The T in the TDD is another one million dollars error leading to the misunderstanding of the concept. For all of you thinking TDD is about testing and you fine to write tests afterwards just replace T with the S as Specification. It's SDD - Specification Driven Development. And now honest answer the question: Are you nuts, to write specification of your implementation after your implementation is done?

  • @nickpll
    @nickpll11 ай бұрын

    Where i find this hard is when a database is thrown into the mix. To truly decouple your test from your implementation in this case you'd have to actually use a real database or mock out all of the calls to your db. Only other option is dependency injection but then you end up exposing the interface for the db. None of these options are ideal and it is what i have struggled most with when it comes to unit testing.

  • @yungifez

    @yungifez

    11 ай бұрын

    Haha when i tried mocking the db i was in for a lot of surprises, i just give up and write feature tests that tests the authorization of the user. Validation and if the data was actually creared, i di test firsts though. Worked out reasonably well for now

  • @JohnWilson-xl3rl

    @JohnWilson-xl3rl

    11 ай бұрын

    Think about in-memory vs i/o tests rather than unit and integration, look up Hexagonal Architecture

  • @andrealaforgia

    @andrealaforgia

    10 ай бұрын

    You can use stubs to emulate the database or just use an in-memory database. It’s perfectly doable.

  • @yungifez

    @yungifez

    10 ай бұрын

    @andrealaforgia I used to use sqlite but I was in for a nasty surprise even while still using an orm Blank positives due to differences in some of their functionslity

  • @ruixue6955
    @ruixue69554 ай бұрын

    0:31 it can't be test-driven unless we are driving the code from test 1:19 end up the project with lots of tests is never really the goal 1:32 goal of TDD:

  • @by_grux
    @by_grux11 ай бұрын

    Great

  • @szeredaiakos
    @szeredaiakos11 ай бұрын

    Well, splitting tests in multiple tiers dictated by the application architecture solves partially the issues. Going from implementation dependent modules to complex business logic. Implementation dependent parts and entire chains usually get deleted and rewritten every time there is a considerable change. Test is code, one should architect it, maintain it and change it according to requirements. Usage of a framework is explicitly forbidden if testing, and quality are strategic goals of your company. Third, tests, TDD and BDD are only THE SECOND factor of ensuring high quality software.

  • @craigiedema1707
    @craigiedema170711 ай бұрын

    I had an argument with a previous employer every time I had to explain something broken to a customer. It was all about poor test design. Nearly all the bugs were because of a change that was unit tested only and broke some other part of the system.

  • @tylerkropp4380

    @tylerkropp4380

    11 ай бұрын

    In some of his other videos, Dave talks about the importance of other kinds of tests as well. Indeed, it sounds like your previous employer didn't have enough integration tests.

  • @craigiedema1707

    @craigiedema1707

    11 ай бұрын

    @@tylerkropp4380 indeed, it was develop and then what you developed matches spec functionality the exact scenario Dave describes as the being written after code.

  • @feliciafasterthanlight5796
    @feliciafasterthanlight579611 ай бұрын

    Ricardo is right that most developers are bad testers at least from what I’ve seen in my decades of experience. It is incentivized that way. Usually developer’s performance is evaluated by how fast they get features working. Few are valued for the quality of their tests or how many bugs they have squashed. Top tier developers are constantly assigned to producing features and it’s the junior staff that gets assigned most of the defects.

  • @nschoem

    @nschoem

    8 ай бұрын

    I absolutely feel this and I think this speaks to a deeper issue on TDD. There's a perception (I don't know if true or not) that test-after has a clear advantage over TDD from a business/product perspective: faster time to market. I think it's this perception that can warp perspectives into saying "Oh it's fine to ship the feature first and then we can write the test later", based on being the first one to market. I would massively prefer to go a bit slower if it keeps the software much easier to evolve; but as a developer I struggle with how to articulate that.

  • @haxi52
    @haxi5211 ай бұрын

    How do you feel about writing tests when bugs are found?

  • @mistalan

    @mistalan

    11 ай бұрын

    What?

  • @peteobryan4650

    @peteobryan4650

    11 ай бұрын

    Test-driven debugging will make you a believer in TDD. Assuming you have a good idea where the problem is in the code, then if it wasn’t written in a testable way, you now have an excuse to refactor it to isolate the failing behavior. On the other hand, if the code was developed through TDD, testable by design, it will be easier to determine the scenarios that you missed, and add tests for them, and congratulate yourself when they fail.

  • @uome2k7

    @uome2k7

    11 ай бұрын

    you add a test that reproduces the bug, it should pass before you make any code change. update the test with the expected behavior so that it fails, again before you change the code. Now change the code to make the test pass. All other tests should still pass as well. This will help prevent regressions.

  • @AndrewSmithDev
    @AndrewSmithDev11 ай бұрын

    My biggest problem with writing tests first is that I'm not sure what will be possible. I might have a idea of how I want it to work but there will be inevitable roadblocks and I will have to iterate to get to the solution I want. Am I supposed to write tests for each iteration only to throw them away later since that solution wont work? That seems like a waste of time

  • @edwardweir5784

    @edwardweir5784

    11 ай бұрын

    I always try and test behavior at a high enough level that I am not likely to want to throw away the tests when I run into a problem. Sometimes that means adding one more test forces you to effectively rewrite all the functionality you have written. But you shouldn't need to rewrite the tests, because the code after your rewrite should still have all the original behavior plus whatever behavior is needed for the new test. These other tests help you refactor safely, because you can be confident you didn't lose anything important in the redesign if all the other tests still pass.

  • @tylerkropp4380

    @tylerkropp4380

    11 ай бұрын

    The spirits of the existing tests are still alive. There would be no reason to remove those tests. Merely refactor them with your new changes. And if you need to remove some tests because you decided to drop functionality - congrats, you just made your requirements simpler! Bear in mind that TDD affects the design of the code, so it's not actually an apples-to-apples comparison. As you gain experience designing code modules, the thrashing diminishes, because you get better at predicting what the design will end up being.

  • @AndrewSmithDev

    @AndrewSmithDev

    11 ай бұрын

    @@edwardweir5784 What if I don't know what the behaviour of the system will be? For example, recently I integrated the OpenAI Chat API into my application. I've never used that API before. I don't know how to use it and I don't know what I can do with it. I could write tests for how I think it will work but as I explore the API and learn how it works, I learn that my original ideas are no longer valid.

  • @edwardweir5784

    @edwardweir5784

    11 ай бұрын

    ​@@AndrewSmithDev Oh I see, you mean for really early development. Or for learning a new system entirely. Then I would say two things. 1. Consider it just a learning phase and don't worry about tests. You are not really writing code with any particular objective. You don't know the requirements. You are just learning. 2. As soon as you know anything at all, you can write a test for it. Remember a smoke test is still a test. You can be calling the code you are playing around with from a testing framework. This will develop into multiple proper tests with asserts as soon as you want to try multiple conditions.

  • @brandonpearman9218
    @brandonpearman921811 ай бұрын

    I read in interesting counter argument called "Test-induced design damage". Don't fully agree with it but interesting.

  • @ddanielsandberg

    @ddanielsandberg

    11 ай бұрын

    As with everything, it's a skill and it takes time to learn. No different than new developers applying all the design patterns on everything - "pattern-induced design damage". It's kind of strange how many devs out there have no problem learning every shiny new framework out there, but when it comes to TDD and test-automation they don't take the time to build the skill (which may take years, like everything else) and then concludes that "TDD is sh*t".

  • @ContinuousDelivery

    @ContinuousDelivery

    11 ай бұрын

    @@ddanielsandberg 💯💯

  • @ContinuousDelivery

    @ContinuousDelivery

    11 ай бұрын

    I certainly recognise that this is a thing, but it is a thing based, as @Daniel Sandberg says, on not learning the skill. TDD *IS* a design technique first and foremost, if you see it as being "all about the testing" you miss a HUGE part of the value and end up with crap, often over-tested, poorly structured code. You pick the next test to allow you to advance your design in a controlled way. If you do that, I don't see how TDD leads to design damage.

  • @brandonpearman9218

    @brandonpearman9218

    11 ай бұрын

    @@ddanielsandberg Yeah, I think what you're saying is not so strange. When devs learn every new shiny tool but tbh I dont think thats the case with the author of "Test-induced design damage", he seems quite knowledgeable on TDD. Personally I'm not for or against TDD, I do it sometimes.

  • @brandonpearman9218

    @brandonpearman9218

    11 ай бұрын

    @@ContinuousDelivery @ddanielsandberg Saying its due to someone not learning the skill is "poisoning the well", because you put TDD in a position where nobody can present a negative because then "they have no skill". The discussion on "Test-induced design damage" was between Martin Fowler, Kent Beck, and David Heinemeier Hansson. I dont think Martin Fowler and Kent Beck would entertain the discussion if David Heinemeier Hansson had no idea what TDD was or "not learning the skill". I'm not saying TDD is bad, I'm just not dogmatic about it. And dont push devs in my team to do it. I personally do training on it but then leave it up to the individual dev.

  • @vincenthernandez1646
    @vincenthernandez164611 ай бұрын

    About 4 years ago, I came across a paper from Microsoft which compared TLD and TDD. One surprising bit that came from the study was that on average, production code in TLD projects was notably smaller that in TDD projects. As others mentioned, TDD is a difficult skill to develop. I sense many new to intermediate TDD developers have a mentality of doing whatever it takes for the tests to pass, consequentially giving code clarity / redundancy second class treatment.

  • @federicobau8651
    @federicobau865111 ай бұрын

    Not matters how much you ll keep repeat thay writtinh test first is better, or how many example you give of the same reason, incompetent and stupid people will never understand i am afraid... that s actually scary. Eitherway us just an observation, please keep doing what you are doijg which is great!

  • @mullla1ya
    @mullla1ya29 күн бұрын

    Why do I feel like Dave is roasting me right now?

  • @ContinuousDelivery

    @ContinuousDelivery

    26 күн бұрын

    😉

  • @spaghettihair
    @spaghettihair11 ай бұрын

    lol Jenkins

  • @davidvernon3119
    @davidvernon311911 ай бұрын

    I’ll give two arguments for testing after the fact. 1) you are in a high pressure - under funded startup scenario with very fluid requirements. If the choice is skipping tests, or the business falls then you skip tests. This is why startups are notorious for low code quality. 2) there is a battery of testing that can only be done after the fact. Acceptance testing, load testing, black box / functional testing to name a few. But with that said i totally agree that ina perfect world code should be grown out of tests. As an example Fred brooks talked in the 80s about code “scaffolds” That has to be built for certain portions of his code. And he talked about throwing those away after a point. These days i would say that those scaffolds are your tests and that they should be kept and maintained.

  • @someoneelse5005

    @someoneelse5005

    11 ай бұрын

    1) This fallacy is assuming that going without tests is faster, but is it really? What you save in 'just getting things out' you pay for in trying to make any change. ESPECIALLY BECAUSE you are expected to change things all the time, you should first change the test to reflect the change, then implement it and get confirmation about this right away. 2) But at this point you might have a system that is barely stitched together and maintaining it will be a nightmare. Also, being able to test something vs being able to write a test for it are two different things. If you cannot write an acceptance test ahead of time, then you have no idea what your system is supposed to be doing. It won't _PASS_ before you write all the code, but you should be able to write it.

  • @davidvernon3119

    @davidvernon3119

    11 ай бұрын

    @@someoneelse5005 have you ever done a high pressure startup? Like where 12 to 16 hour days are the norm? All reason goes out the window. I’m not saying it’s a good way to do things, but it is a reality for some

  • @someoneelse5005

    @someoneelse5005

    11 ай бұрын

    ​@@davidvernon3119 I have, and I left, because people need rest instead of pushing out garbage high on caffeine with lack of sleep so before you tell me why you are not doing tdd tell me why you think working 12+ hr days is not waste of your life.

  • @davidvernon3119

    @davidvernon3119

    11 ай бұрын

    @@someoneelse5005 i’m not promoting developing without testing. I’m simply saying that it’s a luxury that not all are offered. As for the merits of working 12 hours a day, I think there’s a place for it. I worked my ass off in my 20s in my 30s, but did contract work. When I worked 12 hours I got paid for 12 hours. Doing what I call “volunteer work” for the man is in working 12 hours and being paid for eight because you’re on salary. That’s total bullshit. With that said I don’t work those kind of hours anymore. Largely because I don’t need to. When I was young I worked hard and invested conservatively. Today I only work when and if I want to.

  • @francis_n

    @francis_n

    11 ай бұрын

    @@davidvernon3119 1) Dave said in his video that tests written after are better than no tests at all, but it's not a recommendation. As someone who has worked in high pressure start up, I understand the need to deliver quickly. I wouldn't say that this is still a valid argument for test after, though. It's the least one can do with little time. I find there tends to be a misconception that TDD is slow so not worth focusing on, might as well write the tests after the production code is done. The thing is, as one gets more seasoned with TDD, writing them becomes faster and the feedback loop much shorter and saves on the headache of being up at 3am debugging buggy code that was never written with testing in mind. Also in my experience, yours may differ, I find it harder to set up tests for the black box of code that was written without testing in mind. I thus spend more time on writing the tests and trying to get them to go green. These tests are usually poorer quality and slower. 2) These forms of tests are all still necessary, and I believe software projects need them, but these tests are traditionally written afterwards anyway and are slower and tend to test the system as an integration. Unlike TDD, they do not help inform the design of the code, they just assert on a higher level that the entire collection of code is working correctly together. Still IMO not a valid argument for writing test after unit tests.

  • @temper8281
    @temper828111 ай бұрын

    If you write tests before you write code you will need to change the tests when you change the code. There are certain things you cannot learn by just writing tests. You need to write the code in order to learn those things. If you've written tests, you will have to then change the tests. This is painful and can kill the momentum of a project which can be the death of it. Just write tests that test that your code does the thing its supposed to do. Maybe that means writing the tests before, writing after or just testing in a completely different way. Dying on this TDD hill just seems silly to me.

  • @someoneelse5005

    @someoneelse5005

    11 ай бұрын

    If you can't write tests first, then you do not have enough knowledge to start working on the project. If you have to write code first to understand the interface you need to call, you've already failed. If you write a test, and you figure out you need something more from the input, you use this knowledge to add this to a test now, and make sure that any other interface is updated to reflect this. It is an iterative process.

  • @temper8281

    @temper8281

    11 ай бұрын

    @@someoneelse5005 I'm not sure what domain you work in, but in my domain that is just not possible to do. You need a stage where you explore the space and you need to write code to do that. Simply writing the tests will not work because you need to figure out the constraints that you have first. You can't do that writing a test. Sometimes writing the test first is useful. Sometimes writing the code first is useful. Also there can be hidden constraints that aren't obvious until much later in the process. Now you have a bunch of tests that need to change. This is a MASSIVE overhead that adds nothing particularly because tests of that nature really only test you got something right, not how it actually goes wrong.

  • @barneylaurance1865

    @barneylaurance1865

    11 ай бұрын

    TDD doesn't advocate writing "the tests" before writing the code - in the idealised version you just write one simple test, then the code to make it pass, and then repeat. You can use what you learned writing the code for the first test to help you design the second test. Of course in practice sometimes people will write multiple tests at once when they think they won't learn enough by just writing the code to make one test pass.

  • @temper8281

    @temper8281

    11 ай бұрын

    @@barneylaurance1865 are you saying you do or you don't write tests before you write the code? Because your comment is a little confusing

  • @someoneelse5005

    @someoneelse5005

    11 ай бұрын

    @@temper8281 Whether TDD is possible depends a lot on how much the code is dependent on global context. Doing TDD forces you to constrain access to global environments and have a tendency to pass parts of them to functions doing useful work. This is exactly WHY you can do TDD pretty much everywhere - even if your test is not sufficient/correct/requires more context, as you iterate on your code and test you start to find significant design flaws with overlaid infrastructure so you make amends for that. In fact, if you are in charge of the project, and find you can't do TDD, but are given free reign to fix badly structured projects, you might want to prioritize doing that before delving deeper into implementing new features a lot of the time. Except when you try to explain that to management.

  • @lucashowell7653
    @lucashowell765311 ай бұрын

    Why can't we just both test before and after the code? Wouldn't that encourage writing code that lends itself to testing in the most uniform way since you're expecting it on both sides? How about adding a final test that confirms that the two tests are equal, and only executing the code when the two tests come out as equivalent?

  • @francis_n

    @francis_n

    11 ай бұрын

    If the test that you wrote before the code, that goes green validates the code is working, what would be the point of a duplicate test written afterwards that did the same? Correct me if I am misunderstanding you Lucas, but "adding a final test that confirms that the two tests are equal" feels like you're now writing a unit test to test the first unit test. 🤔

  • @lucashowell7653

    @lucashowell7653

    11 ай бұрын

    ​@@francis_n Well, I think the mistake I made is not materially different than the kinds of erroneous reasoning people usually make with TDD... the tests assert that the code does what it does but one could argue the code does what it does regardless of the tests. I feel like no one is being creative enough to innovate a compile-time solution that is nimble enough to take small logical pivot points and USE THEM to instantly and magically fix the code as it compiles. Obviously us as human beings CANNOT write perfect code, so if we want something eventually resembling nearly perfect code, we are going to need some help at a particular moment, and that moment is after we think it's good but before it actually is finalized and RUNS. There's gotta be a way...

  • @zshn
    @zshn11 ай бұрын

    If you follow SOLID and DRY principles, it doesn't matter whether you write tests before or after development; they are very much alike.

  • @awmy3109
    @awmy310911 ай бұрын

    Still disagree that TDD is strictly writing test first. You need to have an idea how you are going to structure what you want to test. The importance of TDD to me is writing testable code not writing test first.

  • @tylerkropp4380

    @tylerkropp4380

    11 ай бұрын

    TDD is defined that way; look it up. It sounds like you're conflating TDD with "writing tests", which the video points out in the first thirty seconds. Don't get me wrong, it's good to test your code, but you're equivocating.

  • @someoneelse5005

    @someoneelse5005

    11 ай бұрын

    Let's say you need a functionality to get square root of a number. By writing tests that assert that, given 4 you get 2, you realize that you need a function that takes one number and gives you back one number. However you also start thinking about actual inputs and then you figure out, alright so if I put 3, I am going to get a decimal number. Maybe entry could be an integer but out needs to be a float? Sooo thinking of inputs... what happens if we put in a zero? How do we handle it, what even IS a square root of zero? Better look that up. Or... what if the number is really big, can we even perform our algorithm in this case? Okay, so let's predict that also in the case we give this function 4, it will reduce 2.0 because it makes sense to standardize return value type. And bam, you come to the conclusion you need a function that takes a float (could also coerce an integer to a float, you don't have a reason to care) and returns a float, you call it something obvious like "sqrt". Let's assume a maximum number that is going to be used with this function is 32/64bit float that we can represent and check how the calculation goes when we run it. Obviously, this is an extremely trivial example, and the exact point is that you DO NOT NEED TO HAVE AN IDEA of how you are going to structure what you want to test. You just need to know what the interface is going to be like - which you define through a test. If this example was more complex, like for instance creating a function that conditionally removes elements of a list based on input, by testing first, you would ensure you don't cover edge scenarios that will never happen - you write tests with realistic inputs that are expected to be handled. But those inputs also CREATE edge cases you might not have thought about dealing with in code otherwise, so you ONLY AND EXCLUSIVELY code what is going to run, not things that aren't. You quite literally get 100% test coverage without even trying. You don't get in a position where you "structured the code" in such a way that there is any excess, because you had no reason to. It won't happen during development. If you find out about an edge case after this and it breaks in a testing environment or production, that is because you did not specify behavior well. The important point is, even if you wrote the code first, you would still not have thought of those edge cases, because you would not really understand how inputs map to outputs without first writing that specification down (like through a test!).

  • @awmy3109

    @awmy3109

    11 ай бұрын

    @@someoneelse5005 Using such simple sqrt examples to explain why you should write test first is the issue. In real world you are going to be testing complex interactions between multiple components not sqrt. Writing test for something you have not even decided what the structure of the interactions will look like is unnecessary back and forth of changing your test and going back to restructure the code. Makes no sense. You don't test a car before manufacturing it. The focus of TDD should shift to writing testable code. Whether you write test first, middle or last has zero benefits if the code is not written to be testable.

  • @francis_n

    @francis_n

    11 ай бұрын

    @@awmy3109 "You don't test a car before manufacturing it", that's true. A car is an entire system comprised of many 'units', the engine being one, which itself is composed of many other subunits. Your software is the system, like the car, and you cannot test drive the entire system. TDD works on smaller units, which should have very clear and granular roles. These can be more easily built up using TDD, as they should be able to function in isolation or prodded at by tests. To confirm the entire system works together, you still have to run integration and end-to-end tests. Building your units up using TDD leads to better, modular and loosely coupled code. I think the greatest resistance to TDD or even trying it is summarised in this entire thread. It's the difficulty to understand how an assertion can be made on code that doesn't exist yet, and neither the idea for it. In my experience of TDD, there's always this back and forth dance between what the code should look like. This dance is good. This is the part where you wrestle with the decision as to how the outward public API could or and eventually should look like, and focus from there on the behaviour of the code. As you write a test, make it go green, refactor, rinse and repeat, you find the code starts to evolve as you notice better ways of writing it. TDD is a constant conversation with yourself and the code, rather than at the end. Not sure how many UI developers are here, but the resistance is even greater for UI developers I work with, as they cannot rationalise how you can ever TDD code for visual elements. Short answer, it can be done and it works!

  • @tiagoperes1631
    @tiagoperes163111 ай бұрын

    Why did I read 'Unix testing is not good enough'?

  • @RicardoSilvaTripcall
    @RicardoSilvaTripcall11 ай бұрын

    My only concern is, usually developers are bad testers ...

  • @7th_CAV_Trooper

    @7th_CAV_Trooper

    11 ай бұрын

    No they aren't.

  • @wwkw4992

    @wwkw4992

    11 ай бұрын

    It depends which code is under test. It is not idea to create the test for your own code

  • @tuV13ja

    @tuV13ja

    Ай бұрын

    Actually Dave says that you should first write your test and after that implement your feature 😅

  • @masafromhell
    @masafromhell11 ай бұрын

    "Test-first fundamentalism is like abstinence-only sex ed: An unrealistic, ineffective morality campaign for self-loathing and shaming." I really like this channel, it offers a lot of interesting insights regarding development from multiple standpoints, except when it comes to TDD. When it comes to TDD, this channel treats it like the bible, and any deviation from thy holy script is blatant heresy! Most developers I know have a positive attitude towards TDD, but none of them actually practices TDD. You can call them crap developers, but isn't that a bit posh and unfair when most developers don't practice TDD? Which brings me to the next question, if TDD is so irrefutably great and TDD has been around for quite some time, why hasn't it become the de facto developing method for most projects?

  • @mistalan

    @mistalan

    11 ай бұрын

    You answered your questions in your comment. Read it again.

  • @masafromhell

    @masafromhell

    11 ай бұрын

    ​@@mistalan very unoriginal and typical brogrammer mentality.

  • @deanschulze3129

    @deanschulze3129

    11 ай бұрын

    @@mistalan Answer his final question. If you try to do that you'll see that your comment is nonsense.

  • @deanschulze3129

    @deanschulze3129

    11 ай бұрын

    "Which brings me to the next question, if TDD is so irrefutably great and TDD has been around for quite some time, why hasn't it become the de facto developing method for most projects?" I've been asking that question for years and no one can answer it. Not Dave Farley, not Ron Jeffries, not Martin Fowler, not Bob Martin, not Kent Beck, not anyone.

  • @ApprendreSansNecessite

    @ApprendreSansNecessite

    11 ай бұрын

    When I spot myself thinking "this content is great except when it is about the things I disagree with", and it happened to me more than a couple of times, it gives me pause. As for the explanation, I would say that if you learned how to program differently, adopting TDD will put you in a bad place for a while. Why go through this trouble and face doubt, unease, make mistakes along the way if you already function as a developer? It is the same with functional programming or agile: you already work in a way that pays the bills, you may hear that there is another way with this and that benefits, you can even try to implement bits of it in your workflow, but you are not going to make the switch, you are not going to change. I would also like to add that in companies there is inertia and legacy: the way of working of your company is going to be transmitted to junior developers.

  • @kB-hg2ci
    @kB-hg2ci11 ай бұрын

    As interesting as your topics are, you couldn't be all that bright when every link I clicked on, in your website led to "Forbidden". How is it that I don't find that at all surprising?

  • @jesperhallborg7720
    @jesperhallborg772011 ай бұрын

    you need to get a better mic

  • @llothar68
    @llothar6811 ай бұрын

    Stop using TDD, it's not worth it.

  • @joonasmakinen4807

    @joonasmakinen4807

    11 ай бұрын

    Start using BDD instead?

  • @someoneelse5005

    @someoneelse5005

    11 ай бұрын

    @@joonasmakinen4807 Haha, good one. @Lothar Well if you want ultimate job security to support a failing project til you are gray, I guess no TDD/BDD is better, because you will be the only one to understand what the code does and be an irreplaceable hero.

Келесі