4 ms·
Well written tests make refactoring a breeze. Poorly written tests make refactoring nigh impossible, and usually don't contribute to anything other than code c
by diob 6y ago
Well written tests make refactoring a breeze.
Poorly written tests make refactoring nigh impossible, and usually don't contribute to anything other than code coverage metrics.
Focus on quality, not quantity.
- postalrat 6y agoWell written tests make trivial refactoring a breeze. High level refactoring means writing new tests. Which often kills the effort before you begin.
- jlmorton 6y agoIt just so happens that minor refactoring is far and away the larger use case. That seems like a pretty good win.
- fenomas 6y ago"Refactoring" normally refers to changing code's implementation without affecting its external behavior. By definition, refactoring should not mean needing to write new tests.
- invalidOrTaken 6y agoThe line demarcating "external" and "internal" can be quite mobile, and moreover, context-dependent. Especially when refactoring.
- chriswarbo 6y agoCould I ask what you mean by "external" and "internal" here? Could different parts of a codebase ever count as "external"?
- quietbritishjim 6y agoI think they are referring to behaviour, not "parts of a codebase", as the GP comment used the phrase "external behavior".
- chriswarbo 6y agoI wouldn't make that assumption. For many people "external" means "in a different class to this one", for others "external" means some other process or service (e.g. a DB like MySQL). It's a widespread problem that people can end up talking past each other, since they make assumptions about the definitions of terminology that other people are using. I've written about this e.g. http://chriswarbo.net/blog/2017-11-10-unit_testing_terminology.html http://chriswarbo.net/blog/2017-11-10-unit_testing_terminolo... and http://chriswarbo.net/blog/2020-07-07-more_testing_terminology.html http://chriswarbo.net/blog/2020-07-07-more_testing_terminolo...
- quietbritishjim 6y agoYou're right that terminology is fluid and people can talk past each other. But you have to draw the line somewhere. The original comment by fenomashas only two sentences, the subject of the first was "external behavior" and the second was on the same topic. The comment after that by invalidOrTaken, which you replied to, is also very short and was specifically asking about fenomashas's use of the word "external". We can be as confident as it is reasonably possible to be that invalidOrTaken therefore was asking about external behaviour, not code. (Incidentally, invalidOrTaken's comment was also about clarity of definition, but not the same difference you were questioning - at least if I understood you right!) My own use of the equivocal language "I think" didn't help here. That was a bit of classic British understatement. But really, the two comments we're talking about are unambiguous.
- chriswarbo 6y agofenomashas's comment seemed clear to me. invalidOrTaken's claim that refactoring can affect what is internal versus external, or that it can be context-dependent, was surprising to me. I would consider changes to what's internal versus external as breaking changes; large changes could plausibly be called redesigns. Certainly not refactorings. The context-dependence of internal/external makes sense, but that makes me think in terms of e.g. "MySQL is external to the application" versus "MySQL is inside the application's container", or even "MySQL is interal to the subnet where the application runs". Architecturally that makes sense, but I don't think it would affect the way I test things, or classify those tests. On the other hand, invalidOrTaken might be using "external" to mean "other classes", in which case it's easy to imagine a refactoring changing all sorts of (class) boundaries. Likewise, the phrase "external behaviour" could simply mean "the public methods of a class". I've certainly worked somewhere that claimed to follow "Behaviour Driven Development", where each "behaviour" was a micro-managed implementation detail of a particular method of a class, with a huge pile of mocks to simulate the behaviour of everything else.
- nevertoolate 6y agoNo! Never change the behaviour and the implementation at the same time! It is the same for a class or function or monoid or whatever. API change and implementation change should never happen at the same time. If you covered the old behaviour with tests (on the appropriate granularity) you can refactor the IMPLEMENTATION and verify that the systems tested invariants hold buy running the tests. There are a lot of books written about this but really the main idea is this simple.
- mbeex 6y ago> "Refactoring" normally refers to changing code's implementation without affecting its external behavior. To verify this invariance, you have to test it. Specifically, and that means new tests.
- UK-Al05 6y agoThose tests for those invariants should already exist, if your already testing.
- deleted 6y ago[deleted]
- treve 6y agoA good typing system and (mostly) functional code also gets you quite far with this.
- humanrebar 6y agoCoverage analysis in particular gets to be overkill when you have a good type system and a good model. But type systems do not help you with things like "do we gracefully fail when we got this error path?" or "do we actually drain the queue in all cases?". Few things but contrived tests do, really.
- marcosdumay 6y agoYes, they do. And your second example is a very usual thing to do with them. (The first isn't common, but is doable, it's common to use types to enforce that failure is handled, not that it fits some extra requisites.)
- qznc 6y agoAgreed. The rant to me reads as "Writing good tests is hard. Bad tests are not worth it." That raises the question how valuable the skill of writing-good-tests is. For quality software or is. For a career unfortunately not in many companies.
- spaetzleesser 6y agoThe problem is that at the time you write your stuff it's not always very clear what's well written and what's poorly written. I often encounter old code written by myself that seemed like a really good idea back then but looking at it now it was just bad.