python ireland nov 2010 talk: unit testing

Post on 19-May-2015

436 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Unit testing for those seeking instant gratification - Maciej Bliziński Abstract: Unit testing has long term benefits. However, depending on how you use it, it can have short term benefits too. This is an introductory talk, aimed at both beginner and experienced Python programmers who would like to get started testing their code.

TRANSCRIPT

Unit testing

For those seeking instant gratification

Maciej Bliziński <blizinski@google.com>Python Ireland 2010-11-10

Helps the designProvides live documentationHelps refactoring

But I'm hungry right now!

I love to see my code run

task: Index a list of dictionaries by one of the fields

def IndexBy(d_list, field_name): result = {} for d in d_list: result[d[field_name]] = d return result

def MakePackageNameBySoname(soname): """Find the package name based on the soname.

Returns a pair of pkgname, catalogname. """ def AddSeparator(d, sep): """Adds a separator based on the neighboring of two digits.""" dc = copy.copy(d) if dc["version"]: if (dc["basename"][-1].isdigit() and dc["version"][0].isdigit()): dc["sep"] = sep else: dc["sep"] = "" else: dc["sep"] = "" return dc soname_re = re.compile(r"(?P<basename>[\w\+]+([\.\-]+[\w\+]+)*)" r"\.so" r"(\.(?P<version>[\d\.]+))?" r"$") m = soname_re.match(soname) if not m: # There was no ".so" component, so it's hardo to figure out which one is # the name, but we'll try to figure out the numeric part of the soname. digits = "".join(re.findall(r"[0-9]+", soname)) alnum = "".join(re.findall(r"[a-zA-Z]+", soname)) parsed = { "basename": alnum, "version": digits, } else: parsed = m.groupdict() keywords_pkgname = {} keywords_catalogname = {}

(continued...)

for key in parsed: if parsed[key]: keywords_pkgname[key] = SonameToStringWithChar(parsed[key], "-") keywords_catalogname[key] = SonameToStringWithChar(parsed[key], "_") else: keywords_pkgname[key] = "" keywords_catalogname[key] = "" pkgname_list = [] keywords_pkgname = AddSeparator(keywords_pkgname, "-") pkgname_list.append( "CSW%(basename)s%(sep)s%(version)s" % keywords_pkgname) keywords_catalogname = AddSeparator(keywords_catalogname, "_") catalogname_list = [ "%(basename)s%(sep)s%(version)s" % keywords_catalogname, ] return pkgname_list, catalogname_list

Real life example

task: Index a list of dictionaries by one of the fields

def IndexBy(d_list, field_name): result = {} for d in d_list: result[d[field_name]] = d return result

import example_1

def main(): d = [{"foo": "a", "bar": "b"}, {"foo": "c", "bar": "d"}] print example_1.IndexBy(d, "foo")

if __name__ == '__main__': main()

import unittestimport example_1import pprint

class IndexByUnitTest(unittest.TestCase):

def testTwoElements(self): d = [{"foo": "a", "bar": "b"}, {"foo": "c", "bar": "d"}] pprint.pprint(example_1.IndexBy(d, "foo"))

if __name__ == '__main__': unittest.main()

import unittestimport example_1

class IndexByUnitTest(unittest.TestCase):

def testTwoElements(self): d = [{"foo": "a", "bar": "b"}, {"foo": "c", "bar": "d"}] expected = { 'a': {'foo': 'a', 'bar': 'b'}, 'c': {'foo': 'c', 'bar': 'd'}, } self.assertEquals(expected, example_1.IndexBy(d, "foo"))

if __name__ == '__main__': unittest.main()

blizinski@workstation ~/unit-test-talk $ python2.6 example_1_test.py .----------------------------------------------------------------------Ran 1 test in 0.000s

OK

Cultured way of playing with code

Changing your code

import unittestimport example_1

class IndexByUnitTest(unittest.TestCase):

def testTwoElements(self): d = [{"foo": "a", "bar": "b"}, {"foo": "c", "bar": "d"}, {"foo": "c", "bar": "e"}] expected = { 'a': {'foo': 'a', 'bar': 'b'}, 'c': {'foo': 'c', 'bar': 'd'}, } self.assertEquals(expected, example_1.IndexBy(d, "foo"))

if __name__ == '__main__': unittest.main()

task: Index a list of dictionaries by one of the fields

def IndexBy(d_list, field_name): result = {} for d in d_list: result.setdefault(d[field_name], []) result[d[field_name]].append(d) return result

Keeping a track record

def testMakePackageNameDashesNoDashes(self): soname = "libpyglib-2.0-python.so.0" expected = ( ['CSWlibpyglib2-0python0'], ['libpyglib2_0python0'], ) self.assertEqual(expected, su.MakePackageNameBySoname(soname))

def testMakePackageNameDashesNoDashesPython(self): soname = "libpython3.1.so.1.0" expected = ( ['CSWlibpython3-1-1-0'], ['libpython3_1_1_0'], ) self.assertEqual(expected, su.MakePackageNameBySoname(soname))

The trust issue

Your first steps in unit testing

Hug me, I only look alien!(never mind my boxing gloves)

It's about the waypieces of code

fit together

Your trust will gradually shift

Part of the development process

It's a tool which helps with some of the everyday tasks.

Further reading

http://en.wikipedia.org/wiki/Unit_testinghttp://diveintopython.org/unit_testing/index.htmlMock objects, stubs and fakes

ContactMaciej Bliziński <blizinski@google.com>

References

Images:

http://commons.wikimedia.org/wiki/File:Pantheon_rome_inside_1-muniu.jpg by Muniuhttp://commons.wikimedia.org/wiki/File:Instant_miso_soup.jpg by Gleamhttp://www.flickr.com/photos/f-oxymoron/4203860207/sizes/l/in/photostream/ by f-oxymoronhttp://www.flickr.com/photos/jurvetson/1381322008/sizes/l/in/photostream/ by jurvetsonhttp://www.flickr.com/photos/7332902@N05/3221210836/ by David O'Driscollhttp://www.flickr.com/photos/edsweeney/4212380812/sizes/o/in/photostream/ by Ed Sweeney

http://www.flickr.com/photos/jenny-pics/3230153121/sizes/l/in/photostream/ by jenny downinghttp://www.flickr.com/photos/oskay/265899766/ by Windell Oskayhttp://www.flickr.com/photos/alismith44/357361903/ by Ali Westhttp://www.flickr.com/photos/cezaryborysiuk/3947857278/ by Cezary Borysiukhttp://www.flickr.com/photos/wilhei/109403331/ by wilhei55http://www.flickr.com/photos/antonymayfield/3221876089/ by antony_mayfieldhttp://www.flickr.com/photos/ralphandjenny/4999895776/ by Ralph Daily

top related