4 ms·
Yes, you should delete tests for everything that isn't a required external behavior, or a bugfix IMO. For the edification of junior programmers who may end up
by _pius 6y ago
Yes, you should delete tests for everything that isn't a required external behavior, or a bugfix IMO.
For the edification of junior programmers who may end up reading this thread, I’m just going to come right out and say it: this is awful advice in general.
For situations where this appears to be good advice, it’s almost certainly indicative of poor testing infrastructure or poorly written tests. For instance, consider the following context from the parent comment:
Otherwise you're implicitly testing the implementation, which makes refactoring impossible.
A big smell here is if the large majority of your tests are mocked. This might mean you're testing at too fine-grained a level.
These two points are in conflict and help clarify why someone might just give up and delete their tests.
The argument for deleting tests appears to be that changing a unit’s implementation will cause you to have to rewrite a bunch of old unrelated tests anyway, making refactoring “impossible.” But indeed that’s (almost) the whole point of mocking! Mocking is one tool used for writing tests that do not vary with unrelated implementations and thus pose no problem when it comes time to refactor.
Now there is a kernel of truth about an inordinate amount of mocking being a code smell, but it’s not about unit tests that are too fine-grained but rather unit tests that aren’t fine-grained enough (trying to test across units) or just a badly designed API. I usually find that if testing my code is annoying, I should revisit how I’ve designed it.
Testing is a surprisingly subtle topic and it takes some time to develop good taste and intuition about how much mocking/stubbing is natural and how much is actually a code smell.
In conclusion, as je42 said below:
Make sure you tests run (very) fast and are stable. Then there is little cost to pay to keep them around.
The key, of course, is learning how to do that. :)
- ptx 6y ago> Mocking is one tool used for writing tests that do not vary with unrelated implementations What if I chose the wrong abstractions (coupling things that shouldn't be coupled and splitting things in the wrong places) and have to refactor the implementation to use different interfaces and different parts? All the tests will be testing the old parts using the old interfaces and will all break.
- dragonwriter 6y agoYou seem to think the rationale is testing performance; but from GP it seems that the rationale is avoiding the tests ossifying implementation details against refactoring rather than protecting external behavior to support refactoring.
- _pius 6y agoI think you wrote this before I finished elaborating on my comment. :)
- VHRanger 6y agoDid you ever actually refactor code with a significant test suite written under heavy mocking? The mocking assumptions generally end up re-creating the behavior creating the ossification. Lots of tests simply mock 3 systems to test that the method calls the 3 mocked systems with the proper API -- in effect testing nothing, while baking in lower level assumptions into tests for people refactoring what actually matters. You might personally be a wizard at designing code to be beautifully mocked, but I've come across a lot of it and most has a higher cost (in hampering refactoring, reducing readability) than benefit.
- _pius 6y agoDid you ever actually refactor code with a significant test suite written under heavy mocking? I have. The assumptions you make in your code are there whether you test them or not. Better to make them explicit. This is why TDD can be useful as a design tool. Bad designs are incredibly annoying to test. :) For example if you have to mock 3 other things every time you test a unit, it may be a good sign that you should reconsider your design not delete all your tests.
- monkpit 6y agoIt sounds like your argument is “software that was designed to be testable is easy to test and refactor”. I think a lot of the gripes in the thread are coming from folks who are in the situation where it’s too late to (practically) add that feature to the codebase.
- UK-Al05 6y agoMocks allow you test a certain method was called, with certain parameters, and in certain order. That's extreme test implementation coupling. Most don't use those features, but in my experience mocks indicate implementation coupling.