[TIP] {Disarmed} Re: Testing multi-threaded applications

Raphael Marvie raphael.marvie at lifl.fr
Fri May 11 02:12:29 PDT 2007


On May 10, 2007, at 7:18 PM, Bernhard Mulder wrote:
>
> That has at least the advantage of being very systematic.
>
> There are two things which I dislike about this solution:
>
> 1. This can lead to a long list of parameters passed around, and  
> obscures the distinction of the parameters which are needed for the  
> algorithmic part, and the once introduced only to satisfy testing  
> requirements. I would prefer for the testing artifacts to be out of  
> the way as much as possible when I read code to understand how it  
> works.

I get you point, in the meantime I do not consider a timeout only as  
a testing artifact. I also consider that such an element is more an  
"object property" than a hard coded value, thus should be  
configurable easily (this is for the timeout value part). Comparing  
our proposals the difference lays mostly in the indirection.

> 2. If you put the testing parameters into some structure (dict or  
> class) to avoid the "testing clutter", and keep the number of  
> parameters at a reasonable number, you are essentially back to the  
> solution I proposed.

Well, when parameters have a default value I am not bothered by their  
number, but this is purely personal. I consider them as object  
properties and not test related information.

> 3. If you read the call to sleep, "self.sleep", you have to  
> remember that self.sleep is really time.sleep, except for testing.

but as my __init__() sets this value, the reader know what it mean by  
default. On this I do not see the difference between our two solutions.

> My first attempt was to put all such system functions into one  
> module. Something like:
>
> Systeminterface.py:
>
> class time(object):
>     from time import sleep, time
>
> However, the class definition transforms function into methods, and  
> I have to add extra code to transform the method back into a  
> function. I now think it is simpler to make Systeminterfaces into a  
> module, and then create a time module as a part of that package.  
> Systeminterfaces.mytime would simply be:
>
> from time import sleep
>
> [Not sure if I can name this module time and somehow get the time  
> module from the distribution in the import statement, instead of  
> the current module].
>
> Then, to use sleep in a module, I can say:
> from SytemInterfaces.mytime import sleep
>
> My current code is something like this:
> from SystemInterfaces import time
> sleep = time.sleep

yes but you do not know what is the real implementation behind neither.

> >To some point, externalizing the opening of files.
>
> I suppose by "externalizing the opening of files" you mean  
> introduce a class which handles the interface to the file system,  
> like creating directories, querying the file system, etc?

nope. I meant if function x needs to write to something that may be a  
file I prefer to pass an object that provides the write function and  
do the opening outside of the function itself.

def write_data_to_file(self, filename):
     """Open filename for writing and use write_data for completion"""
     f = open(filename, 'w')
     self.write_data(f)
     f.close()

def write_data(self, output):
     """Write data to the provided output object.

     output has to provide a write() function.
     """
     # my complex algorithm
     output.write(data_to_be_written)
     # ...

So that each function has a clean responsibility and write_data can  
be easily tested and used  with something else that a file if needed.

This express my 'divide to conquer' / 'the best method is the one  
that does nothing' implementation and design strategy.

r.

--
Raphael Marvie, PhD                http://www.lifl.fr/~marvie/
Maître de Conférences / Associate Professor  @  LIFL -- IRCICA
Directeur du Master Informatique Professionnel spécialité IAGL
Head of Master's in Software Engineering     +33 3 28 77 85 83





More information about the testing-in-python mailing list