Is there a cleaner way to show implementation details for testing?

I know there is a popular notion that implementation details do not require testing and / or that implementation should be made public. For the sake of this question, please take note that there is merit for both testing and minifying the API.

How should an internal free function be tested?

// Example for C
static MyType do_something_internal(OtherType * X);
// Or (roughly) equivalently
namespace { MyType do_something_internal(OtherType * X); }

      

The option we are currently running is to expose the call, but in the part namespace:

// Preserve the friendly function name and internal linkage
static MyType do_something_internal(OtherType * X)
extern MyType detail_do_something_internal(OtherType *X)
  { return do_something_internal(OtherType *X); }

// C++ version preserving the external linkage of the original
namespace detail {MyType do_something_internal(OtherType * X);}

      

Instead, we could open a single object containing references to internal functions:

struct exposed_for_test {
  auto detail_do_something_internal = do_something_internal;
  auto detail_other = other;
} // Similar in C, but somewhat less convenient to write out

      

We could wrap the testing interface in preprocessor macros with varying degrees of care:

#ifndef TESTING_BUILD
#define LINKAGE extern
#else
#define LINKAGE static
#endif
LINKAGE MyType do_something_internal(OtherType * X)
// or:
#ifdef TESTING_BUILD
static MyType do_something_internal(OtherType * X);
extern MyType detail_do_something_internal(OtherType * X)
{ return MyType do_something_internal(OtherType * X); }
#endif

      

I am currently leaning towards the latter option. Any non-test code that calls the public interface will not be able to be referenced in the release build. However, this seems to inevitably double the compile time, and is a little awkward to test different object files for the released ones. It might be better to leave the test interface in place and rely on connection time optimizations to turn it off.

I am also considering writing test code with release code to access static functions directly. This clogs "real code" with "test code", although it is probably a controversial decision.

All of the above options seem pretty crude, so I would like to ask the community - do you have any better ideas or are you using one of the above? Thank.

+3


source to share


2 answers


When you're ready to move on to "embedding" the test code, how about including the * .cc file in the * _test.cc file? In my humble opinion, often helper functions can make a home in another file where they are public functions. Otherwise, they are too small and insignificant to test, or their role is undefined. Yes, it is possible that no one else will ever use this other * _helper_util.h interface, but this is true for a lot of code. Right?



+1


source


this link: https://ved789.wordpress.com/2009/11/27/coupling-cohesion-encapsulation-polymorphism/

cohesion, cohesion, encapsulation, polymorphism are discussed.

for the purposes of this question, the main interest is "chaining":

Here's what the link has to say about "connection"

(not particularly the first sentence.)



Binding is the unnecessary dependency of one component on the implementation of other components.

this link: http://searchsqlserver.techtarget.com/definition/data-hiding

defines hiding data as:

Data hiding is a characteristic of object-oriented programming. Since an object can only be associated with data in predefined classes or templates, an object can only "know" about the data it needs to know about. There is no way that someone who maintains the code could inadvertently point out or otherwise accidentally receive incorrect data. Thus, all data not required by the object can be called "hidden. "

All of the above means that the data / implementation should be hidden. In large projects, this becomes a serious problem.

-2


source







All Articles