Comments by "" (@grokitall) on "Why Would Anyone Hate TDD? | Prime Reacts" video.

  1. the main problem here is that prime and his followers are responding to the wrong video. this video is aimed at people who already understand 10+ textbooks worth of stuff with lots of agreed upon terminology, and is aimed at explaining to them why the tdd haters don't get it, most of which comes down to the fact that the multiple fields involved build on top of each other, and the haters don't actually share the same definitions for many of the terms, or of the processes involved. in fact in a lot of cases, especially within this thread, the definitions the commentators use directly contradict the standard usage within the field. in the field of testing, testing is split into lots of different types, including unit testing, integration testing, acceptance testing, regression testing, exploratory testing, and lots of others, if you read any textbook on testing, a unit test is very small, blindingly fast, does not usually include io in any form, and does not usually include state across calls or long involved setup and teardown stages. typically a unit test will only address one line of code, and will be a single assert that when given a particular input, it will respond with the same output every time. everything else is usually an integration test. you will then have a set of unit tests that provide complete coverage for a function. this set of unit tests is then used as regression tests to determine if the latest change to the codebase has broken the function by virtue of asserting as a group that the change to the codebase has not changed the behaviour of the function. pretty much all of the available research says that the only way to scale this is to automate it. tdd uses this understanding by asserting that the regression test for the next line of code should be written before you write that line of code, and because the tests are very simple and very fast, you can run them against the file at every change and still work fast. because you keep them around, and they are fast, you can quickly determine if a change in behaviour in one place broke behaviour somewhere else, as soon as you make the change. this makes debugging trivial, as you know exactly what you just changed, and because you gave your tests meaningful names, you know exactly what that broke. continuous integration reruns the tests on every change, and runs both unit tests and integration tests to show that the code continues to do what it did before, nothing more. this is designed to run fast, and fail faster. when all the tests pass, the build is described as being green. when you add the new test, but not the code, you now have a failing test, and the entire build fails, showing that the system as a whole is not ready to release, nothing more. the build is then described as being red. this is where the red-green terminology comes from, and it is used to show that the green build is ready to check in to version control, which is an integral part of continuous integration. this combination of unit and integration tests is used to show that the system does what the programmer believes the code should do. if this is all you do, you still accumulate technical debt, so tdd adds the refactoring step to manage and reduce technical debt. refactoring is defined as changing the code in such a way that the functional requirements do not change, and this is tested by rerunning the regression tests to demonstrate that indeed the changes to the code have improved the structure without changing the functional behaviour of the code. this can be deleting dead code, merging duplicate code so you only need to maintain it in one place, or one of hundreds of different behaviour preserving changes in the code which improves it. during the refactoring step, no functional changes to the code are allowed. adding a test for a bug, or to make the code do something more happens at the stsrt of the next cycle. continuous delivery then builds on top of this by adding acceptance tests which confirm that the code does what the customer thinks it should be doing. continuous deployment builds on top of continuous delivery to make it so that the whole system can be deployed with a single push of a button, and this is what is used by netflix for software, hp for printer development, tesla and spacex for their assembly lines, and lots of other companies for lots of things. the people in this thread have conflated unit tests, integration tests and acceptance tests all under the heading of unit tests, which is not how the wider testing community uses the term. they have also advocated for the deletion of all regression tests based on unit tests. a lot of the talk about needing to know about the requirements in advance is based upon this idea that a unit test is a massive, slow, complex thing with large setup and teardown, but it is not how it is used in tdd. there you are only required to understand how to write the next line of code well enough that you can write a unit test for that line what will act as a regression test. this appears to be where a lot of the confusion seems to be coming from. in short, in tdd you have three steps: 1, understand the needs of the next line of code well enough that you can write a regression test for it, write the test, and confirm that it fails. 2, write enough of that line that it makes the test pass. 3, use functionally preserving refactorings to improve the organisation of the codebase. then go around the loop again. if during stages 2 and 3 you think of any other changes to make to the code, add them to a todo list, and then you can pick one to do on the next cycle. this expanding todo list is what causes the tests to drive the design. you do something extra for flakey tests, but that is ouside the scope off tdd, and is part of continuous integration. it should be pointed out that both android and chromeos both use the ideas of continuous integration with extremely high levels of unit testing. tdd fits naturally in this process, which is why so many companies using ci also use tdd, and why so many users of tdd do not want to go back to the old methods.
    1