Hacker News new | past | comments | ask | show | jobs | submit login

Testable code is not a good thing in and of itself. Code should only be testable at its high level interfaces i.e. interfaces that are close to the requirements. So if the code is a library then the high level interface may be the public interface of a class. In that case you may need single class tests. But to do anything useful (in the sense of high level requirements) most code use a combination of various different classes or modules. Write tests at this level because it gives you two advantages:

1) If you decide to change your implementation (refactor low-level code to make it more performant/re-usable/maintainable) then you won't have to change your tests.

2) It will simplify your implementation code.

The second point is as important as the first: In general your code should have the minimum number of abstractions needed to satisfy your requirements (including requirements for re-use/flexibility etc). Testable code often introduces new abstractions or indirections just for the sake of making it possible to plug in a test. One or two of these are OK. But when you add up all the plug points for low level tests in a system it can make the code a lot more complex and indirect than it needs to be. This actually makes it harder to change which was not the idea behind making it testable in the first place.

Gui code may be an exception here. Because gui's are often slow and unstable to test it is worth cleanly separating the gui from the model just to make the system more testable, even if you never intend to use the model with any other kind of ui (the usual motivator for separating model and gui). Any model-view system will help here. If you have a system where the gui is more or less a pure function of the model then you can write all your scenario/stateful tests at the model level and just write a few tests for the ui to verify that it reflects the model accurately




Well-structured code is a good thing in and of itself, and more testable code is inherently more well-structured (or rather, untestable code is inherently badly structured; it's still possible to have testable but badly structured code, but if you insist your code be testable then you will avoid many of the pitfalls)


> Testable code is not a good thing in and of itself. Code should only be testable at its high level interfaces i.e. interfaces that are close to the requirements. So if the code is a library then the high level interface may be the public interface of a class.

Perhaps I misunderstand you, but I have to disagree with this.

Testable code is absolutely a good thing in and of itself.

When something breaks, being able to isolate each piece of the codebase and figure out why it's breaking is essential.

Far too often I've got bug reports from other developers saying "System X is broken, what changed?". When I ask for more detail, a test case proving it's broken, etc - they can't come up with that. Their test case is "our entire service is broken and I think the last thing that happened was related to X". Sometimes it is a problem with System X, but more frequently it's something else in their application.

The smaller you can make your test case, the better, and the easier it is to get a grasp of the acutal problem.


The cost of modifying simple tests is negligible. Getting your tests to that point is a big shift in how people interact with them.

Modifying complicated tests can be unbounded, and I think a lot of the pushback comes from these situation.

It is very possible to create tests that are worse than doing nothing. It can be a roadmap for learned helplessness, too.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: