Should Unit Tests Test Internal Functions

A little background here: I'm coding in CommonLisp, attempting to practice ExtremeProgrammingForOne; this is my first experience with XP. Thus far I've been very happy with the process, and can't imagine how I programmed any other way. Now, CommonLisp has the notion of packages; it's not necessary, but I consider it good style, for packages to exist in 1:1 with source files in most cases.

A package is composed of symbols; each symbol can be internal or external. When package A "uses" package B (calls the function use-package on it; symbols from any package are accessible to any package, with a little extra syntax, from any other package, whether one uses the other or not), then the external symbols of B are directly visible to A. To access the internal symbols of B, extra syntax is needed. There is no way to make the internal symbols of a package be truly "hidden" and inaccessible to any other package, unlike in C++, Java, etc.

Here, then, is the question. --DanielKnapp

Should unit tests be written for functions which are not intended to be accessible outside of a given (small) part of the program?

For the moment, I believe that they should, when possible; they act to document those functions for the use of the programmer. The argument against would be that they constitute looking too deeply into a module's internals; by their nature, they certainly cannot be written before the module is implemented. The counter-counter-argument would be that they don't replace tests which were written first, only supplement them.


The answer to the question in the topic is obviously not. As long as the external interface works, who cares about the internal functions?

Then you are really performing a system test and not a unit test. --AnonymousDonor


I use the following two criteria for deciding whether a function should be unit tested(*):

So if I have an internal function that's likely to have bugs in it and that can be easily unit-tested, then I do so. In fact I find myself writing unit tests for internal functions a lot. Since public functions call internal functions more frequently than the other way around, internal functions tend to be simpler in behavior, and consequently they are (I claim) easier to test.

I should probably point out that I put my unit tests in the same file as the functions they are testing.

(*)One should, of course, aspire to writing functions that are both easy to test and unlikely to have bugs.

-- CurtisBartley


Doesn't this level of detail in tests inhibit refactoring? I can preserve the operation of a public function while drastically changing the internal functions it relies upon. I am not sure I see the benefit of rewriting both internal functions and tests simultaneously. --WayneMack


Terminology becomes a detriment when you get hamstrung by it. The rule for testing is: If you have low confidence in it, test it. Now then, what shall we call your test? Contrast this approach with, say, setting out to "unit test everything"...

-- WaldenMathews


see also ShouldUnitTestsTestInteroperations


EditText of this page (last edited October 24, 2001) or FindPage with title or text search