adding a simulation mode

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Jul 4 15:41:56 CEST 2012


On Wed, 04 Jul 2012 10:42:56 +0100, andrea crotti wrote:

> I'm writing a program which has to interact with many external
> resources, at least:
> - mysql database
> - perforce
> - shared mounts
> - files on disk
> 
> And the logic is quite complex, because there are many possible paths to
> follow depending on some other parameters. This program even needs to
> run on many virtual machines at the same time so the interaction is
> another thing I need to check...
> 
> Now I successfully managed to mock the database with sqlalchemy and only
> the fields I actually need, but I now would like to simulate also
> everything else.
> 
> I would like for example that if I simulate I can pass a fake database,
> a fake configuration and get the log of what exactly would happen.  But
> I'm not sure how to implement it now..  One possibility would be to have
> a global variable (PRETEND_ONLY = False) that if set should be checked
> before every potentially system-dependent command.

I think a better way would be to use a mock database, etc. For each thing 
which you want to simulate, create a class that has the same interface 
but a simulated implementation.

Then, have your code accept the thing as an argument.

E.g. instead of having a hard-coded database connection, allow the 
database connection to be set (perhaps as an argument, perhaps as a 
config option, etc.).

There are libraries to help with mocks, e.g.:

http://garybernhardt.github.com/python-mock-comparison/
 

> For example
> 
> copytree(src, dest) becomes:
> if not PRETEND_ONLY:
>     copytree(src, dest)

Ewww :(

Mocking the file system is probably the hardest part, because you 
generally don't have a "FileSystem" object available to be replaced. In 
effect, your program has one giant global variable, the file system. 
Worse, it's not even a named variable, it's hard-coded everywhere you use 
it.

I don't know of any good solution for that. I've often thought about it, 
but don't have an answer.

I suppose you could monkey-patch a bunch of stuff:

if ONLY_PRETEND:
     open = my_mock_open
     copytree = my_mock_copytree
     # etc. 
main()  # run your application



but that would also be painful.


-- 
Steven



More information about the Python-list mailing list