5 ms·
Just Null might be a bit limited, however there are many other similar issues (some examples I can think of include functions which take a positive integer, or
by CJefferson 14y ago
Just Null might be a bit limited, however there are many other similar issues (some examples I can think of include functions which take a positive integer, or a non-empty container, or a sorted container, or two containers of equal size, or an integer which is smaller than the size of another argument, which is a container).
I used to be very slack on internal checks. As times goes by I have pushed more of these into the type system where appropriate, and as checks. While unit tests on your external API can be useful, it can be hard to ensure coverage of all the nasty corner cases of your internals, some of which are only hit one time a million, or hundred million.
I find having all these checks makes me more confident about changing my internal APIs. If anyone is calling a function inappropriately for it's new interface, I will quickly get an assertion flagged up, as opposed to code carrying on calling a function incorrectly.
Just so we aren't talking at cross purposes, I feel I should say most of my programming is algorithmic, particularly in AI. In this field it can be devilishly difficult to construct good unit tests and ways of hitting bits of algorithms -- I am currently working on an algorithm which has function which I believe is required but which I cannot construct test data for my external API which causes it be called. Always a little worrying!
- lmm 14y ago>As times goes by I have pushed more of these into the type system where appropriate Yeah, the type system is the appropriate place for most of these (including null even). >I find having all these checks makes me more confident about changing my internal APIs. If anyone is calling a function inappropriately for it's new interface, I will quickly get an assertion flagged up, as opposed to code carrying on calling a function incorrectly. I think we may be talking at cross purposes wrt "public". I don't mean "only ever test your external API". I do mean "only ever test public methods of a class, in the technical sense of public". Of course a large project will end up with lower-level and higher-level layers, and eventually you do need to define more rigid boundaries between the two to avoid everything becoming an unmaintainable mess, and testing at these boundaries is entirely appropriate. But a single class should belong to one layer or another. >I am currently working on an algorithm which has function which I believe is required but which I cannot construct test data for my external API which causes it be called. Always a little worrying! More than a little. My advice (not that you need it) would be to try and encode the constraint that leads to it not being called in the type system, then push it up through the layers.