DEV Community

loading...

Discussion on: TDD Practicality

Collapse
sargalias profile image
Spyros Argalias • Edited

Other responses have already touched on the value of testing, prototypes and time to market. I agree with those sentiments. In more detail, it may make more business sense to ignore the overhead of tests to be first to market. However, in a large project, in my experience, tests provide a lot of long-term benefits, both in development speed and robustness of the software.

However, you don't need TDD to write good tests.

So I'll give my opinion on whether the technique / workflow is worth it compared to writing tests afterwards.

The benefits, of TDD, in my experience, are that:

  • it forces you to design the public API of what you're about to code ahead of time (because that's what your tests will call). This can result in better designed code, that's easier to use.
  • it ensures your code will be tested
  • it encourages your code to be simple and decoupled (clean) (it needs to be, otherwise it would be hard to test)
  • it forces you into a very small development loop. You code a tiny part of a feature (which is very easy to do) and test it, ensuring it's stable. This almost completely eliminates debugging compared to programming for 30 minutes, then testing your work and having to debug multiple little mistakes to get it working
  • it forces you to write a failing test first. Failing tests are good because they ensure your test isn't passing when it shouldn't. It's more efficient to write it first, rather than write a normal test, then deliberately make it fail and then fix it again.

But you don't actually need TDD to do any of those things. For example, you could design the public API of your code ahead of time, even without TDD, or refactor into a good public API. You can also write the same clean code with TDD or without. And so on.

TDD is just a nice and efficient process for doing those things. Also, TDD forces you to do them, even if you normally wouldn't.

As a final note. I normally can only do TDD if I have some idea of what the solution / public API is going to be. If I have no idea of what to do, I either:

  • create a small prototype (try some stuff out in code) without tests. Then re-write it properly with TDD.
  • code until something works. Then refactor my code and add tests. The resulting code should be equivalent to what I would have written with TDD.

What are your thoughts (or anyone else's) on this?

Collapse
cariehl profile image
Cooper Riehl

Great response! I really appreciate that you made it clear you're not "against" TDD, while still explaining some situations where it's not a silver bullet.

I'm curious to hear about your experience with writing code first and then adding tests, versus using TDD from the start. How often do you find one approach is more useful than the other? Are there certain types of projects that are easier to work on with one of those two approaches? Let me know!

Collapse
sargalias profile image
Spyros Argalias

Thank you :). In general I do TDD whenever I can (assuming I'm not working on something where I wouldn't write tests). I think it's a very efficient workflow, for many reasons.

But as I mentioned, you can get the benefits of TDD by doing them manually. TDD is slightly more efficient, for example, as mentioned above, for writing a failing test.

So for me personally. I feel a very small difference when using TDD or not using it.

However, I imagine that there are many people who wouldn't do anything that TDD helps you with unless they used TDD. For them, TDD would be a much more efficient process and result in much cleaner code.

When I don't use TDD

If I write tests and if I have a general idea of what I need to do, I use TDD. If I'm not sure what to do, I mess around with code a bit first, until I have a general idea of what to do.

Unfortunately, I can't think of a good example at the moment. Let's say, for the sake of example, that you have no idea what your implementation should be. You then mess with some code and discover that promises may be good to use. At this point, you have some idea of what kind of tests you can write. So you can either re-write the code with TDD, or just refactor what you've got so far and add tests.

When I don't write tests at all

This is a separate topic to TDD, but in general I don't write tests if I'm creating a quick prototype for something. That's because I don't need the code to be robust, and I'm not going to be working on the code for months to come. I just need something quick and dirty to see if I've got the right idea in what I'm creating. Spending time writing tests will probably just be wasted time.

Another example is some hobby game development I've been doing. I've learned that, during initial development, I change how things work a lot. In other words, things stay in the trial or prototype stage for a long time. For these kinds of projects, I'm avoiding writing tests more and more, until I feel like the requirements are more stable. (Or until I feel like I'm spending too much time debugging and I'd rather automate the bug-finding process by writing tests.)

The thing with tests is that they aren't free. They take time to create. Further, if you change the public API of the code, you also need to modify the tests. So they make it harder to make large changes. So, for prototype code where things may change a lot, tests are too costly. They are worth it in enterprise projects because their benefits outweigh their costs. They reduce bugs in your code (critical for real applications but not important for prototypes), they reduce time spent debugging and reduce time to do manual testing (which would be significant in large applications, but low in small applications or prototypes).

Okay, that was an essay... I hope it's somewhat useful. If you have any questions, comments or even different opinions, let me know :).

Thread Thread
cariehl profile image
Cooper Riehl • Edited

I love and appreciate this "essay"! I read the whole thing, and I think you and I have similar thoughts on TDD in general. I especially agree with this point:

I've learned that, during initial development, I change how things work a lot. In other words, things stay in the trial or prototype stage for a long time. For these kinds of projects, I'm avoiding writing tests more and more, until I feel like the requirements are more stable.

I am the same way. When I work on my personal projects, I tend to spend way more time reorganizing systems, just because I find it enjoyable. If I forced myself to write tests for every change, I would get way less enjoyment out of my projects, which would defeat the purpose! I program as a hobby because I find it fun, not because I feel the need to create a useful product. That's what programming professionally is for ;)

I do try to force myself to remember TDD principles whenever starting a new project, and I'll often start by writing a few tests for a component. But similar to you, as soon as the tests get in the way of my enjoyment/productivity, I stop forcing myself to write them. In a workplace setting, I would be more hesitant to abandon my TDD approach; but in a hobby setting, the only person I'm trying to please is myself.

Thanks for your response :) if you have a response to this one, I'll happily keep the conversation going!

Thread Thread
sargalias profile image
Spyros Argalias

Nice yeah, seems like we have similar thoughts indeed :).

Thread Thread
bertilmuth profile image
Bertil Muth

One situation where I don't use TDD is when I need to call some framework/library methods, but don't know how to use it yet. I would rather "play around" with the library a bit, until I know how to use it, without writing tests, and then start my own development based on it.

Thread Thread
sargalias profile image
Spyros Argalias

Good example, thanks :)

Forem Open with the Forem app