browse: forums | FAQ
Connecting Tech Pros Worldwide

Hey there! Do you need Python help?

Get answers from our community of Python experts on BYTES! It's free.

unittest help

Qiangning Hong
Guest
 
Posts: n/a
#1: Jul 19 '05
I want to apply TDD (test driven development) on my project. I am
working on a class like this (in plan):

# file: myclass.py
import _extmod

class MyClass(object):
def __init__(self):
self.handle = _extmod.open()

def __del__(self):
_extmod.close(self.handle)

def some_stuff(self):
_extmod.foobar(self.handle)

...

As you see, it is an OO wrapper on _extmod, which is a pyrex extension
module. The question is: how to unittest this class? As the _extmod
is hardware-dependent, I want to use a mock class to replace it in unit
test. But how can I let myclass in unittest to import the mock class?
Like the following:

class MyClassTest(unittest.TestCase):
def setUp(self):
import myclass
import mocklib
myclass.change_extmod(mocklib.MockExtMod())
self.testobj = myclass.MyClass() # here MyClass.__init__ will
call the open
# method of MockExtMod class
instead of
# _extmod.open()
...

How to implement the change_extmod? (Or maybe my idea is totally
wrong?)




André Malo
Guest
 
Posts: n/a
#2: Jul 19 '05

re: unittest help


* "Qiangning Hong" <hongqn@gmail.com> wrote:
[color=blue]
> I want to apply TDD (test driven development) on my project. I am
> working on a class like this (in plan):
>
> # file: myclass.py
> import _extmod
>
> class MyClass(object):
> def __init__(self):
> self.handle = _extmod.open()
>
> def __del__(self):
> _extmod.close(self.handle)
>
> def some_stuff(self):
> _extmod.foobar(self.handle)
>
> ...
>
> As you see, it is an OO wrapper on _extmod, which is a pyrex extension
> module. The question is: how to unittest this class? As the _extmod
> is hardware-dependent, I want to use a mock class to replace it in unit
> test. But how can I let myclass in unittest to import the mock class?[/color]

You need to design for testability, meaning in this case, that your class could
to do something like this:

class MyClass(object):
def __init__(self):
self._loadExtmod()
self.handle = self._extmod.open()

def __del__(self):
self._extmod.close(self.handle)

def _loadExtmod(self):
import _extmod
self._extmod = extmod

def some_stuff(self):
self._extmod.foobar(self.handle)

Now just overload _loadExtmod and provide the mock class there.

HTH, nd
Duncan Booth
Guest
 
Posts: n/a
#3: Jul 19 '05

re: unittest help


Qiangning Hong wrote:
[color=blue]
> As you see, it is an OO wrapper on _extmod, which is a pyrex extension
> module. The question is: how to unittest this class? As the _extmod
> is hardware-dependent, I want to use a mock class to replace it in unit
> test. But how can I let myclass in unittest to import the mock class?
> Like the following:
>
> class MyClassTest(unittest.TestCase):
> def setUp(self):
> import myclass
> import mocklib
> myclass.change_extmod(mocklib.MockExtMod())
> self.testobj = myclass.MyClass() # here MyClass.__init__ will
> call the open
> # method of MockExtMod class
> instead of
> # _extmod.open()
> ...
>
> How to implement the change_extmod? (Or maybe my idea is totally
> wrong?)
>[/color]

One way is simply to do:

def setUp(self):
import myclass
self.real_extmod = myclass._extmod
myclass._extmod = mocklib.MockExtMod()
self.testobj = myclass.MyClass()

def tearDown(self):
import myclass
if hasattr(self, testobj):
del self.testobj
myclass._extmod = self.real_extmod

This can be less intrusive than passing the mock object to a constructor,
but it depends very much on the way the objects are used: changing global
state for a unit test is a risky business, for example if an exception is
thrown then tearDown would be called *before* your __del__ method is
invoked. You can work round this by ensuring that the _extmod value is
saved in your instance but that takes you pretty much back to André Malo's
suggestion.

BTW, accessing a global variable from a __del__ method is a bad idea
generally: there is no guarantee that the global variable will still be set
if __del__ is called during program exit.

Scott David Daniels
Guest
 
Posts: n/a
#4: Jul 19 '05

re: unittest help


Duncan Booth wrote:[color=blue]
> Qiangning Hong wrote:
>
>[color=green]
>>As you see, it is an OO wrapper on _extmod, which is a pyrex extension
>>module. The question is: how to unittest this class? As the _extmod
>>is hardware-dependent, I want to use a mock class to replace it in unit
>>test. But how can I let myclass in unittest to import the mock class?
>>Like the following:[/color][/color]

Given:[color=blue][color=green]
>> # file: myclass.py
>> import _extmod
>> class MyClass(object):
>> def __init__(self):
>> self.handle = _extmod.open()
>> ...[/color][/color]

One other way to do your unit test stuff is:
# file: test_myclass.py

import sys, bogus_extmod # First, get the fake hardware
sys.modules['_extmod'] = bogus_extmod # then make that active

import myclass, unittest # and now do all you normally would do
...
class SimplestTests(unittest.TestCase):
...

Note that the "module switch" must happen very early (probably at
the top of the main program).

--Scott David Daniels
Scott.Daniels@Acm.Org

Closed Thread