Live data from Hacker News

Ask HN: Help me see why everyone seems to love TDD?

news.ycombinator.com

71–80 of 89 posts

Re: Ask HN: Help me see why everyone seems to love TDD?

#71
post #63

The deal with TDD is you write twice as much code and you have less than half the bugs. As the project grows, it gets harder and harder to maintain and change unless you have good tests. Most projects without good tests that I've seen grow to a certain size and then become very difficult to make progress on because people are too scared of breaking things and the releases inevitably take a very long time due to all t…

Problem is, tests don't scale well, if you project grows, your test suite grows too. The fear of breaking something will become the fear to not only rewrite the code but also having to rewrite an enormous amount of tests. Also, having "more" things break other things in a big project is more of a modularization/encapsulation kind of issue, that doesn't get better or worse with tests. At the moment I'm looking into st…

It seems like you're talking about the problem of having overly fragile tests. Getting a test to break when something is actually broken is something that comes with experience and studying good tests.

For example, a novice test writer would serialize a Java object and compare it against a previously serialized object byte for byte. This would break as soon as there was a trivial change to the object. A better procedure would be to run pre-test and post-test assertions on the properties of the object that were actually important.

If you have good tests and change something and a bunch of the tests breaks, that simply means you broke a lot of stuff. At least you'll know what's broken instead of having it thrown back and forth over the wall between Dev and QA a hundred times to get it out the door.

Re: Ask HN: Help me see why everyone seems to love TDD?

#72
tldr; read kent beck's original book on the topic before you form your opinion. TDD is not a silver bullet and it's not 100% required to write quality software. but it is a useful tool, and you probably are doing it wrong. if someone taught you at work or school, there is a good chance they were doing it wrong. if you still don't see the point after kent's book and the video that i've linked below, then at least you know the most common arguments for both sides now.

i'm a proponent of TDD and unit testing but i don't TDD all the things. there is, as in all things, a balanced to be achieved between test coverage and delivery time. some parts of the system - primarily the business logic - need thorough testing. other parts of the system, especially those that don't change often, can require less testing. additionally, many people and organizations misinterpret the basic concept behind what Kent Beck describes in his book and end up implementing lots of complicated, brittle tests that eat development time and slow down the entire process.

#1 read Kent's book. seriously, do this now. don't just assume you understand TDD because it sounds so obviously simple #2 watch Ian Cooper's excellent talk: TDD Where Did it All Go Wrong? https://vimeo.com/68375232

i will say that, even after nearly a decade of writing tests, i didn't really understand why my tests were so brittle until i watched #2. turns out i didn't realize what a 'unit' _really_ was, WRT writing tests.

now that you know how and what to test, a few tips: #1 keep "unit tests" separate from "integration tests": - unit tests do not do any actual I/O, run very fast, test "units" in isolation - integration/system tests run over entire systems or sub-systems, rather than isolated units - actually do I/O: db, disk, etc - are slow, but you don't need that many of them if you have good unit test coverage - this point will be made more clear in the video linked above #2 write tests to an interface, not to an implementation - when you write a test that depends on implementation details, it will be brittle and cause trouble when that implementation changes - when you write a test to an interface, the implementation details should be irrelevant (to a degree). you care about the "what" (inputs/outputs/exceptions), not the "how" #3 inversion of control and dependency injection are your friends - the video linked above should give you an idea of what i'm talking about, WRT hexagonal architecture - if you create an object in the function under test, it's hard to manipulate that object to drive the test - if the function under test accepts that object as a param, you can configure it before calling the test or replace it with a mock object #4 be wary of overuse of mocks! - when you end up with tests that are just lots of mock expectations describing the interaction between two objects, you are testing implementation! - lose the mocks and write a system test instead #5 tests are production code! you will need to put the same effort into making them readable and maintainable. you might even have to write tests for some of your test support code

Re: Ask HN: Help me see why everyone seems to love TDD?

#73
post #72

tldr; read kent beck's original book on the topic before you form your opinion. TDD is not a silver bullet and it's not 100% required to write quality software. but it is a useful tool, and you probably are doing it wrong. if someone taught you at work or school, there is a good chance they were doing it wrong. if you still don't see the point after kent's book and the video that i've linked below, then at least you…

omg l2format

Re: Ask HN: Help me see why everyone seems to love TDD?

#74

Earlier quoted context omitted.

I'm not sure I understand your perspective. If you have a specification (shouldn't a web app have a specification? Admittedly, I've never developed one, my world is embedded), then you have something to write your tests too. While we don't use unit tests in my office, we do use comprehensive testing and a (mostly) TDD style (accidentally or coincidentally, our process has operated in roughly the same way for 30 years…

> If you have a specification... A specification doesn't translate directly into code. Otherwise, developers wouldn't have jobs. A specification is interpreted by developers, then reinterpreted by other developers, managers, etc., then updated, etc.

You can create your own specification from the stakeholders' requirements. If you can't create a specification, how do you define what you're programming in order to develop towards some goal?

Re: Ask HN: Help me see why everyone seems to love TDD?

#75
I don't believe TDD adds any value whatsoever to the development process. Nor do I think pair programming is a good idea. I will not work for any employer that mandates those practices.

I'm aware that many people see things differently than I do. That's fine with me. I'm not going to try to change anyone's mind.

Re: Ask HN: Help me see why everyone seems to love TDD?

#76

Earlier quoted context omitted.

> If you have a specification... A specification doesn't translate directly into code. Otherwise, developers wouldn't have jobs. A specification is interpreted by developers, then reinterpreted by other developers, managers, etc., then updated, etc.

You can create your own specification from the stakeholders' requirements. If you can't create a specification, how do you define what you're programming in order to develop towards some goal?

Can you paste an example specification for a small program?

I use a whiteboard (or paper), as do many others, to diagram things out, as a means to put a program's abstract form into my brain. That whiteboard doesn't contain the entire program.

Re: Ask HN: Help me see why everyone seems to love TDD?

#77
post #43

Have you actually lived in a TDD world? Actually sat down and did the entire thing? I don't think it is worth it. Tests are good. Fire manual QA team and hire people to write automated integration tests. But actually designing your code around tests? It tends to lead to brittle systems that do a lot of dumb things. Write the code what works best, then add some tests around it where required. 40% coverage could be eno…

I don't understand why people seem to think that testers could or should be replaced by automated tests. I've worked a lot with test automation, and I find it super important to have automated tests for any long-living project, but one of their main purposes are to off-load the manual testers from doing repetitive regression testing, and focus on more creative exploratory testing - things that humans (well, some) are…

I have had people I trust a lot more than myself argue this. That humans are better exploratory testers than robots.

Totally agree that humans doing manual regressions is bad. I would almost argue that needing humans to do regressions means that something is broke in your coding / testing / deployment process. If page X must REALLY do Y and always work, why aren't you testing it on 30 browsers automatically? Even a very good human would have a hard time matching what you can code automagically.

I trust that there is something there though in humans for exploratory testing. And indeed I have worked with good QA people over the years that found awesome stuff. But I have also worked with many man QA that have added massive negative value to projects. Perhaps I let reality taint my taste of QA?

Re: Ask HN: Help me see why everyone seems to love TDD?

#78

Have you actually lived in a TDD world? Actually sat down and did the entire thing? I don't think it is worth it. Tests are good. Fire manual QA team and hire people to write automated integration tests. But actually designing your code around tests? It tends to lead to brittle systems that do a lot of dumb things. Write the code what works best, then add some tests around it where required. 40% coverage could be eno…

We have automated tests of all types, covering almost everything, but we still find use in our QA team. They also help us write BDD tests.

Sure, I think a QA team writing tests is good. I maybe think QA teams doing exploratory testing is good. The rows and rows of QA in cube farms doing regression testing? That is not good.

Re: Ask HN: Help me see why everyone seems to love TDD?

#79

Earlier quoted context omitted.

You can create your own specification from the stakeholders' requirements. If you can't create a specification, how do you define what you're programming in order to develop towards some goal?

Can you paste an example specification for a small program? I use a whiteboard (or paper), as do many others, to diagram things out, as a means to put a program's abstract form into my brain. That whiteboard doesn't contain the entire program.

I don't have one at hand. The last one I did, a one-off for testing (contractor provided software had issues, we couldn't test because of that, wrote a subset of its features).

The specification can vary, but you still need a specification. In that case what I ended up with was an org file that detailed the timeline for the program (had 3 states for initialization, then went into execution state), the various tasks (embedded system, roughly comparable to threads or processes, but no parallelism potential, more a logical breakdown of the program structure).

I had a set of messages described as potential inputs, a set of messages described as responses. Another set of messages that I sent periodically (description included when they were to be sent and what their contents were supposed to be).

In this case, like I said before, we didn't have unit tests. It was more equivalent to integration tests. But we used a subset of our test suite to verify that (with this fake-driver in place) the software we were developing was properly sending and receiving inputs. So we were able to reuse existing testing infrastructure. Also, in this case, every test "failed". But the portions of it that we cared about passed (well enough, my messages weren't as dynamic as the real thing so the failures were all expected failures).

The org file was, more or less, like this:

  * Driver [/]
  ** TODO States [/]
      - [ ] Initialize - INIT
        Configure shared memory so other applications can access it
      - [ ] Wait for core - CORE_WAIT
        Wait for core to write value X to location Y.
      - [ ] Wait for app - APP_WAIT
        Wait for app to reach ready state
  ** TODO CORE_WAIT [/]
      - [ ] Some details on what we actually cared about here
  ** TODO Input Messages [/]
      - [ ] Message X
        Details on format, later turned into a C struct
      - [ ] Message Y
        Details on how it should change the driver state
      - [ ] Message Z
        Details on how we should respond (with Messages A, B, C)
        - [[MSG_A]] is used when Z.field = 0 
        - [[MSG_B]] is used when Z.field = 1
  ** TODO Output Messages [/]
  *** TODO Responses [/]
      - [ ] > Message A
        Sent in response to Z if Z.field = 0
      - [ ] > Message B
        Sent in response to Z if Z.field = 1
  *** TODO Periodic (not responses) [/]
      - [ ] > Message D
That's a specification (with details removed). This is how I generally write things. Start off with an outline, fill it in. Create links to other areas of the specification, resources like message specification (ours is a very domain-specific one, but others might just be RFCs on more standard or common protocols), language or library documentation, with org-mode you can link directly to source code (I don't utilize this as much as I'd like). A side benefit here is that I can tie it in with my task management system. And tracking progress is automatically done (the [/] bits will tally the number of completed tasks and the total, in emacs this is also colored red/green (default) so I can quickly see what's left).

Want a diagram, that's fine. In my office that means a visio document. I'd make that and link to the file as well. I actually did, in this case, link to a few provided diagrams. Perhaps instead of the detailed text on the message format, I link directly to a specification for message formats. I sometimes write one-off programs to test out the provided libraries or test my actual understanding of the hardware we're running on (useful, because it's often not compliant to the specification, still under development). I almost always (I'd say 80%) write my code like this these days (last 2 years in particular, less consistent before that, and before that I was a tester). Any program that's more than 50 lines of (typically) C, ends up getting this treatment.

I recognize that it's somewhat easier in my primary domain (embedded systems). We generally deal with smaller programs (< 30k SLOC of C), usually know exactly what the inputs and outputs ought to be. In other domains you have to be more flexible. But this structure isn't inherently rigid. Providing a specification, even if it's piecemeal, is better than not as it gives you something to measure against.

Re: Ask HN: Help me see why everyone seems to love TDD?

#80
post #43

Earlier quoted context omitted.

I don't understand why people seem to think that testers could or should be replaced by automated tests. I've worked a lot with test automation, and I find it super important to have automated tests for any long-living project, but one of their main purposes are to off-load the manual testers from doing repetitive regression testing, and focus on more creative exploratory testing - things that humans (well, some) are…

I have had people I trust a lot more than myself argue this. That humans are better exploratory testers than robots. Totally agree that humans doing manual regressions is bad. I would almost argue that needing humans to do regressions means that something is broke in your coding / testing / deployment process. If page X must REALLY do Y and always work, why aren't you testing it on 30 browsers automatically? Even a v…

One thing is that a lot of testers are still working in a very rigid way. First, design and write down the test cases (based on a specification that is most likely flawed and incomplete). Then, perform the tests. Then, document the results. There is very little room for creativity and exploration in such a process.

This is basically what you do when you write automated tests, except the execution (and reporting) steps will be done automatically and repeatedly. Which is super valuable, but when a skilled tester goes at it, there will be ideas and crazy connections flying around everywhere. Even if many of these tests were to be automated (which in many cases really isn't feasible, considering implementation time/execution time/maintainability costs), you'd need someone to even think up the tests, and typically developers don't have the time or breadth of knowledge of their system to do it.

I used to work in a team with 5 developers and me as the tester. Besides finding tons of bugs - many of them very subtle - I became the one person who understood the product best since I was the only one touching all parts of it, so I was the one people came to for questions. Now, working as a developer, I do write automated tests, but I refuse to release anything our tester haven't had the time to test yet.

Post reply on HN