34 ms·
It seems that the boundaries of what a unit test should cover have never been clearly defined. In my opinion, unit testing should only cover logic that does no
by u801e 6y ago
It seems that the boundaries of what a unit test should cover have never been clearly defined. In my opinion, unit testing should only cover logic that does not have side effects (like writing to disk or communicating over a network). If you want to test external side effects, you should write functional or integration tests for them.
- pydry 6y agoI wish more people believed this. The number of lines of code I've seen written of pointless unit tests is staggering. If your code is mostly passing data around and managing side effects a unit test is more like a parasite. It will couple to your code and fail noisily when refactoring but not provide any actual useful feedback.
- closeparen 6y agoMy armchair psychoanalysis is that it’s precisely poor effort:reward ratio that makes people feel superior for writing and demanding them. Look at me, I am a responsible engineer who tests thoroughly, you childish cowboys are trying to wriggle out of doing your chores. No, I’m still going to sweep the floor, just not with a toothpick.
- gnusty_gnurc 6y agoUnit tests are fine for testing side effects if you've written the code properly with proper interfaces, etc. You need to test that you're using the contracts you've made, and integration tests verify that everything works as expected when both sides are complying with the contract. I'm saying that if I've abstracted out the filesystem into an interface the distinction of asserting against whether a method was called on that interface and asserting a side-effect is somewhat trivial. I've made it so that side-effects must be handled in integration tests.
- u801e 6y ago> I'm saying that if I've abstracted out the filesystem into an interface the distinction of asserting against whether a method was called on that interface and asserting a side-effect is somewhat trivial. But now you're enforcing a degree of coupling between your filesystem interface and your code. If you refactor the filesytem interface such that the overall logic hasn't changed, but the parameter order for one of the methods is updated, then you essentially double the amount of work you have to do (update the code and update the tests). If you just test the logic and not the interface, then you only have to update the tests that pertain to the logic itself. You should read up on the concept of functional core/imperative shell.
- gnusty_gnurc 6y agoAh ok, I see what you're saying. I've seen the talk "Hoist your I/O" by Brandon Rhodes. He mentions that but I don't think he went into detail about commands/events or any of that stuff.
- brlewis 6y agoI don't think clearly defined boundaries are what's needed. People just need to keep in mind that the purpose of tests is to catch bugs. When I modify this code, what tests will tell me that it still does what it's supposed to? Keeping that question at the fore will work better than any cookbook.
- u801e 6y ago> When I modify this code, what tests will tell me that it still does what it's supposed to? While that's true, you don't want to end up in a situation where the test is enforcing coupling which makes it harder to refactor your code. So, for instance, if you have tests that assert whether the method tested calls another method with certain parameters in a certain order, then you're enforcing coupling between the two methods. If you refactor the code to have the first method return a result and then use that result to call the second method, then you also have to update the tests. But they shouldn't have to be updated since the overall logic hasn't changed. If, instead, you test the logic of each method individually, then you can refactor and not have to update the tests.
- brlewis 6y ago> While that's true, you don't want I'm confused. These opening words make it sound like you're getting ready to partially disagree, but then the rest of the comment is pure agreement. What did I miss?
- u801e 6y agoAfter re-reading your original comment, there doesn't appear to be enough detail to say one way or another whether we're in agreement. Specifically, you didn't mention or address the issue of tests enforcing coupling between different components.
- brlewis 6y agoYou applied this question: When I modify this code, what tests will tell me that it still does what it's supposed to? To this situation: When I modify this code, will tests that enforce coupling between different components tell me that the code still does what it's supposed to? You observed that no, such tests would need to be changed even though the overall logic was the same. I assume that next you would apply the same question to a test that is for the overall logic, and conclude that yes, it's a good test.