3 ms·
How do you all feel about the need to rewrite a unit test when code gets refactored or business logic changes, isn’t that like a huge pita?
by m3kw9 3y ago
How do you all feel about the need to rewrite a unit test when code gets refactored or business logic changes, isn’t that like a huge pita?
- macshome 3y agoGenerally refactoring is where I find tests to be super valuable. If it’s a pure refactor then the existing tests shouldn’t break. If they start failing, then you have done something that has changed the expected behavior. For business logic I would change the tests first so that it represents the new expected result. Then you refactor the code until the tests pass.
- kuchenbecker 3y agoIf you're testing implementation details rather than contracts, you're susceptible to this. Make sure the unit yutare testing is the thing you want to observe the behavior of.
- coldbrewed 3y agoI treat unit tests like double-entry bookkeeping; I wouldn't describe it as a particular pain and consider it more of a matter of due diligence. Not everything needs this level of rigor but there are plenty of cases where the tests are very cheap to write and reason about (for many pure functions) or are worth the cost as they validate critical behavior. Unit tests also add some design pressure to keep more logic pure/side-effect free; sure, it may take a bit more work to factor your code accordingly to keep i/o interactions separated to the shell of the application but I find this to be a useful pressure. I've found that if I'm encountering pain when writing unit tests, then the pain is due to one of the following things: 1. The code is growing too complex and I need to decompose the logic or refactor the tests 2. The code has grown too many unintentional side effects and I need to move those side effects to discrete components 3. The code under test has fundamental side effects and those side effects require testing, thus the unit tests need to be converted to an integration test 4. The code under test is sufficiently complex that it demands full system/acceptance testing There are some cases where refactoring the tests is generally too painful and I'll throw away all the tests entirely, maybe sprinkle in a few tests for logic that seems critical, and move on. Tests can accumulate technical debt, but in contrast to implementing code it's pretty cheap to cut your losses on tests and wipe them out. I see a lot of people conflating unit testing with the idea that all code must have tests, and there's a ton of code that's phenomenally painful to test and can be easily checked by the developer. Tests should be a supporting tool an an augment to the developer practices; it's better to have some tests that work well and throw out the ones that are miserable to write rather than require 95% test coverage, drown in testing, and throw out all tests entirely.
- m3kw9 3y agoThanks for that response, it was helpful esp about the side effects
- myaccountonhn 3y agoMy experience is that the tests should either test functions that are small and do one thing (I.E. sorts, maps with some logic, basically where you want to test edge cases and sanity check). In those cases there is very little reason to change that code. If you are testing something larger, the test should be an integration test, where you test the full business logic flow. That makes the code less PITA to change while still giving you confidence. If the business logic actually changes, the tests should break IMO because they are there to ensure that the business logic remains consistent. When you test the business logic (without testing the implementation) the code becomes much safer to modify and refactor.