https://linkedrecords.com/the-big-tdd-misunderstanding-8e22c2f1fc21?gi=61ce87d573e8 Open in app Sign up Sign in [ ] Write Sign up Sign in [1] The Big TDD Misunderstanding Oliver Wolf Oliver Wolf * Follow 3 min read * Mar 13, 2022 -- Listen Share Originally, the term "unit" in "unit test" referred not to the system under test but to the test itself. This implies that the test can be executed as one unit and does not rely on other tests running upfront (see here and here). However, when people started considering parts of the system under test as the "units", it significantly affected the quality of test suites (in a bad way). The primary consequence was that the majority began writing one "unit test" for every class or method. The second consequence was the isolation of this "unit" from other "units" using test doubles (mocks). Now, you change a little thing in your code base, and the only thing the testing suite tells you is that you will be busy the rest of the day rewriting false positive test cases. Unfortunately, the status quo of unit testing is perceived very dogmatic and thinking different is kind of a taboo topic. But maybe it helps when you know that there are actually two main schools when it comes to testing: mockist vs. classicist. Here are my tips on how to write "good" tests, mostly inspired by the classicist style. But also keep in mind - in software engineering - there is not good and bad, there is only: does if satisfy your requirements. Tip #1: Write the tests from outside in. With this, I mean you should write your tests from a realistic user perspective. To have the best quality assurance and refactor resistance, you would write e2e or integration tests. This can lead to tests that take a long time to execute and increase the feedback loop. You can try to solve this by making the tests independent of each other so they can run in parallel. Originally, the test pyramid forbade a lot of end-to-end and integration tests. Instead, the pyramid says we should write a lot of unit tests, and for most people, a unit is a class. This often leads to an inside-out approach, testing the structure of the system rather than its behavior. Challenge the traditional testing pyramid and think about how much end-to-end integration and unit tests make sense in your context. Also consider more recent alternatives to the test pyramid: "Honeycomb" and "The Testing Trophy". Tip #2: Do not isolate code when you test it. If you do so, the tests become fragile and will not help you in case you refactor the software. Only isolate your code from truly external services. Have a look at the port and adapter pattern (aka hexagonal architecture), which is a good starting point for decoupling your "main code" from infrastructure code. If you stub, you stub the infrastructure implementations. Also, consider not stub the infrastructure and using a real database. With tools like Docker, it is not that hard or slow anymore. Also, the more you isolate your "unit" under test, the less meaningful the test coverage report becomes. You just don't know if your system works as a whole, even though each line is tested. This is especially true for dynamically typed languages. Tip #3: Never change your code without having a red test. This is a pretty common practice in TDD. This has two benefits: 1) It is the tests of the tests itself. When it is red, you know it works. 2) It makes sure you test all scenarios. This, of course, does not apply when you refactor your code. Tip #4: TDD says the process of writing tests first will/should drive the design of your software. I never understood this. Maybe this works for other people but it does not work for me. It is software architecture 101 -- Non-functional requirements (NFR) define your architecture. NFR usually do not play a role when writing unit tests. To sum up, in my opinion, the most important decision to make when you start writing automated tests is to decide what trade-off to make. Do you want a high level of quality assurance, refactor resistance, or a fast feedback loop? Today, it is often possible to make an e2e test or integration test run fast enough. Programming Coding DevOps Software Development JavaScript -- -- Oliver Wolf Follow Written by Oliver Wolf 103 Followers Working on https://www.monsterwriter.app/ Follow More from Oliver Wolf Jest, Enzyme vs Cypress.js Oliver Wolf Oliver Wolf in Dev Genius Jest, Enzyme vs Cypress.js Today I had to write tests for some React.js components and wondered If it would not be smarter to use Cypress.js for this purpose. I know... 1 min read*Dec 22, 2020 -- 1 The Big DevOps Misunderstanding Oliver Wolf Oliver Wolf The Big DevOps Misunderstanding When the term DevOps came up it was all about a simple idea: 2 min read*Apr 19, 2021 -- 6 Code Optimizations when Using Async/Await Oliver Wolf Oliver Wolf in Dev Genius Code Optimizations when Using Async/Await Async/Await has been introduced to JavaScript in order to cope with the problem called the callback hell. Before async/await a couple of... 2 min read*Jan 3, 2022 -- 1 TypeScript -- Toolchain or Troublechain Oliver Wolf Oliver Wolf in JavaScript in Plain English TypeScript -- Toolchain or Troublechain I only recently started using TypeScript for a personal project. I had my reservations, fearing that it would simply be the next... 2 min read*Sep 28 -- See all from Oliver Wolf Recommended from Medium My favorite coding question to give candidates Carlos Arguelles Carlos Arguelles My favorite coding question to give candidates A coding question, from the viewpoint of an Google/Amazon/Microsoft interviewer 10 min read*Nov 12 -- 33 JSON is incredibly slow: Here's What's Faster! Vaishnav Manoj Vaishnav Manoj in DataX Journal JSON is incredibly slow: Here's What's Faster! Unlocking the Need for Speed: Optimizing JSON Performance for Lightning-Fast Apps and Finding Alternatives to it! 16 min read*Sep 28 -- 121 Lists [1] [0] [1] General Coding Knowledge 20 stories*583 saves [1] [1] Stories to Help You Grow as a Software Developer 19 stories*563 saves [0] [1] [1] Coding & Development 11 stories*272 saves [1] [1] Casually dressed colleagues discussing feedback in front of colourful paintings Leadership 39 stories*145 saves Java and NoSQL Databases: Integration and Best Practices Alexander Obregon Alexander Obregon Java and NoSQL Databases: Integration and Best Practices Introduction 7 min read*4 days ago -- Polymorphism in C# Alex Tolson Alex Tolson Polymorphism in C# Polymorphism, meaning many forms, in object-oriented programming is when an object, method, or entity, performs different operations based... 3 min read*6 days ago -- OpenAI Just Killed an Entire Market in 45 Minutes Ignacio de Gregorio Ignacio de Gregorio OpenAI Just Killed an Entire Market in 45 Minutes The Story Everyone Should Have Seen Coming *6 min read*Nov 9 -- 181 Forget your Microservices! The Unparalleled Benefits of Pool Architecture. Raphael Moutard Raphael Moutard Forget your Microservices! The Unparalleled Benefits of Pool Architecture. When monoliths are the solution to your scaling challenges. 6 min read*Nov 5 -- 16 See more recommendations Help Status About Careers Blog Privacy Terms Text to speech Teams