Pages

Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Monday, 25 April 2011

Calling only once setUp in unittest in python

In python unittest the setUp function gets called every time you need to run a single TestCase (no matter if you run it using TestSuite or simply unittest.main()).

So if you have to test something that requires a complex setUp routine (like loading 50000 records from SQL or preparing an orangemochafrappuccino) but that can be reused all along your TestSuite you have the same problem I had.

Now all around the internet there are posts saying "You could do that" or "One way to do that" or "Once I did that like this..." or even worse "The standard way of doing it is...".

But none of these posts really gets to the bottom of it, they all give you a piece of information. I couldn't find one place that told you "copy/paste this code and be happy".

So, after figuring it out, I can now tell you "copy/paste this code and be happy".
import unittest
from my_program import MyClass

class MyClassTest(unittest.TestCase):
    # First define a class variable that determines 
    # if setUp was ever run
    ClassIsSetup = False

    def setUp(self):
        # If it was not setup yet, do it
        if not self.ClassIsSetup:
            print "Initializing testing environment"
            # run the real setup
            self.setupClass()
            # remember that it was setup already
            self.__class__.ClassIsSetup = True
                               
    def setupClass(self):
        # Do the real setup
        unittest.TestCase.setUp(self)
        # you want to have persistent things to test
        self.__class__.myclass = MyClass()
        # (you can call this later with self.myclass)

You can do the same for the unittest.tearDown since it is exactly the same code.

Mocking LDAP calls with minimock in python

When using unittest in python you often need to mock objects and calls to those objects.

You don't need _an_entire_ LDAP server just to test a search nor you need a full blown SMTP server to test a function that accidentally sends a mail (that you don't want to send while testing anyway).

So minimock is one easy way (the easiest I found) to do the job.

What the docs don't really tell you (nor does a google search) is how to return real things when you need to call a method of an object.

Say you have some code like this:
import ldap
class MyClass:
...
    def ldapsearch(self, uid):
        self.conn = ldap.open(self.conf.ldapserver)
        self.conn.bind_s(binddn, bindpw, ldap.AUTH_SIMPLE)
        self.conn.search_s(basedn, ldap.SCOPE_SUBTREE, 'uid=%s' % uid, ['uid'])
        return True

and you want to test this and moreover you want that search to return a given set of data.

from minimock import Mock
import ldap
from my_program import MyClass

class MyClassTest(unittest.TestCase):
...
    def test_ldapsearch(self):
        # create your fake ldap connection
        ldap.open = Mock('ldap.open')
        ldap.open.mock_returns = Mock('ldap_connection')
        # instantiate your class
        myclass = MyClass()
        # now tell to minimock that in case we do a search_s on 
        # a conn method this should be intercepted and mocked
        # returning a testuser1 value the way LDAP would do
        myclass.conn.search_s.mock_returns = [[1,{'uid':['testuser1'], \
                                        'mail':['test.user1@mail.com']}]]
        # This will return testuser1 no matter what
        # and show you on screen the operations performed
        self.assertEqual(myclass.ldapsearch('onetwoonetwo'), True)

This should help you inject whatever values you want there and also clarify a bit how to minimock wants you to think (that is the only way I could make it work).

Sunday, 8 June 2008

MiMMS: My first OSS project :D

I started to work on MiMMS, an MMS stream downloader written in python.

When I first looked at the application it looked pretty much what I needed to download Italian TV shows to my N810 and watch them while I was on the bus (trying to take advantage of dead periods). The little problem was that (as for many other mms servers) the bandwidth was limited and it was taking me an hour to download just one show.
So I registered a new branch of MiMMS that allows you to split the stream in many parts and use all your bandwidth to be quicker. It still has a lot of work to do, but it works pretty well and I hope it'll soon be packaged for Debian.

Enjoy ;)

Tuesday, 29 January 2008

Complex LDAP queries with python

I came across this nasty problem today and the solution was so easy and stupid that it took me 10 minutes to understand what it was after many tries... :D

Say that you want to make a quite complex query to an LDAP directory using ldapsearch, the syntax is:
ldapsearch -x -h ldap.server.com -b o=Myorganization "&(uid=john*)(!(jobgrade=boss))(address=*Washington*)"

Now to do the same thing with python ldap module I expected the syntax would be the same... well no! (don't know why?).
import ldap
l = ldap.open('ldap.server.com')
res = l.search_s('o=Myorganization', ldap.SCOPE_SUBTREE, '(&(uid=john*)(!(jobgrade=boss))(address=*Washington*))')

so you have simply to add brackets before the & (or |)... again I wonder why it was implemented differently...

Sunday, 29 July 2007

Code like a Pythonist

Wonderful pager with many hints on how to (properly) write consistent code in python.

Thanks to Tim Peters for sharing this precious document. really worth to take a look at it.

Meravigliosa pagina con molti suggerimenti su come scrivere codice in python.

Grazie a Tim Peters per aver scritto questo prezioso documento, vale davvero la pena di dargli un'occhiata.

Friday, 27 July 2007

Photogallery and django

Stockphoto it's a project that aims to offer "an easy way to add a photogallery section to a (django) website".

Still didn't test it and no screenshots available... so what to say... I'll try it :D