NYCPHP Meetup

NYPHP.org

[nycphp-talk] Why do unit tests not inherit?

Robert Stoll rstoll at tutteli.ch
Tue Dec 10 05:59:18 EST 2013


> -----Original Message-----
> From: talk-bounces at lists.nyphp.org [mailto:talk-bounces at lists.nyphp.org] On Behalf Of Gary A. Mort
> Sent: Wednesday, December 04, 2013 9:27 PM
> To: talk at lists.nyphp.org
> Subject: Re: [nycphp-talk] Why do unit tests not inherit?
> 
> 
> Mostly the situation I was trying to describe but not get into nitty
> details are situations where you have external dependencies.
> 
> Take storing data to a cache of some sort as a really good example.
> 
> The lifecycle of a cache engine could be:
> 1) Abstact CacheEngine class where you define an isSupported method
> which will always return false since you can't store items in the
> abstract class.  [Yes, with PHP 5.4+ this would instead be better
> defined as an interface, but we can't all refuse to support 5.3. :-)]
> 
> 2) A child class, CacheEngineMemcache where you can run some check to
> see if Memcache works[on my mind mainly because I just had to create a
> new class for this in Joomla, CacheEngineGaeMemcache because the Joomla
> platform checks to see if the Memcache extension is loaded AND the
> Memcache class exists in it's implementation. Google happens to provide
> both free and paid usage of Memcache for Google App Engine - but they
> don't use the PHP Memcache extension, the code is included in their GAE
> extension to interface with their setup.]
> 
> 3) A third child class, CacheEngineMemcached which since it shares 90%
> of the same code as Memcache, subclasses CacheEngineMemcache but
> modifies isSupported to check for Memcached instead.
> 
> 
> So you have 3 classes each implementing the same method[isSupported]
> which will return either true or false depending on some underlying
> configuration.   Using various PHP extensions it's possible to
> dynamically load/unload the extension so you can confirm your tests - as
> long as isSupported always returns true and false.
> 
> 
> Things get extended, changed, modified beyond belief.  Some day for some
> reason, someone may decide that for their engine, they may return 3
> instead of TRUE for isSupported under some odd situation - maybe to
> indicate the version of something being supported.  Due to the beautiful
> nature of PHP, when doing simple true/false checks 3 will show up as
> true, so it is a very easy way to be backwardly compatible and add some
> extra function.
> 
> 
> One answer is, of course, "well, that was a bad design decision.  I
> don't see any reason to design unit tests to prevent bad design decisions."
> 

My approach works only for own code/libraries/frameworks and theoretically for third party test code which was written
with extensibility in mind. But to be honest, I think I have never written whole unit-tests suites against third party
code. I have written sometimes a few simple unit-tests just to figure out how the third party library works but that was
it.

If I really create a sub-class of a third party class (most of the time I chose aggregation or composition instead) then
I would test every method and wouldn't really bother whether the third party code has its own tests or not (along the
lines of "trust is good, control is better").

I think writing unit test with extensibility of the test code itself in mind is not yet a best practice and I for myself
started writing unit tests this way no longer than a year ago. If extensibility of test code should become a best
practice then I might stick to my approach and go more often for sub-classes of third party code where appropriate.

Cheers,
Robert




More information about the talk mailing list