Python Ireland Nov 2010 Talk: Unit Testing

28
Unit testing For those seeking instant gratification Maciej Bliziński <[email protected]> Python Ireland 2010-11-10

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 of Python Ireland Nov 2010 Talk: Unit Testing

Page 1: Python Ireland Nov 2010 Talk: Unit Testing

Unit testing

For those seeking instant gratification

Maciej Bliziński <[email protected]>Python Ireland 2010-11-10

Page 2: Python Ireland Nov 2010 Talk: Unit Testing

Helps the designProvides live documentationHelps refactoring

Page 3: Python Ireland Nov 2010 Talk: Unit Testing

But I'm hungry right now!

Page 4: Python Ireland Nov 2010 Talk: Unit Testing

I love to see my code run

Page 5: Python Ireland Nov 2010 Talk: Unit Testing
Page 6: Python Ireland Nov 2010 Talk: Unit Testing

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

Page 7: Python Ireland Nov 2010 Talk: Unit Testing

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

Page 8: Python Ireland Nov 2010 Talk: Unit Testing

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

Page 9: Python Ireland Nov 2010 Talk: Unit Testing

import example_1

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

if __name__ == '__main__': main()

Page 10: Python Ireland Nov 2010 Talk: Unit Testing

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()

Page 11: Python Ireland Nov 2010 Talk: Unit Testing

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()

Page 12: Python Ireland Nov 2010 Talk: Unit Testing

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

OK

Page 13: Python Ireland Nov 2010 Talk: Unit Testing

Cultured way of playing with code

Page 14: Python Ireland Nov 2010 Talk: Unit Testing

Changing your code

Page 15: Python Ireland Nov 2010 Talk: Unit Testing

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()

Page 16: Python Ireland Nov 2010 Talk: Unit Testing
Page 17: Python Ireland Nov 2010 Talk: Unit Testing

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

Page 18: Python Ireland Nov 2010 Talk: Unit Testing

Keeping a track record

Page 19: Python Ireland Nov 2010 Talk: Unit Testing

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))

Page 20: Python Ireland Nov 2010 Talk: Unit Testing

The trust issue

Your first steps in unit testing

Page 21: Python Ireland Nov 2010 Talk: Unit Testing

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

Page 22: Python Ireland Nov 2010 Talk: Unit Testing
Page 23: Python Ireland Nov 2010 Talk: Unit Testing

It's about the waypieces of code

fit together

Page 24: Python Ireland Nov 2010 Talk: Unit Testing

Your trust will gradually shift

Page 25: Python Ireland Nov 2010 Talk: Unit Testing

Part of the development process

Page 26: Python Ireland Nov 2010 Talk: Unit Testing

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

Page 27: Python Ireland Nov 2010 Talk: Unit Testing

Further reading

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

ContactMaciej Bliziński <[email protected]>

Page 28: Python Ireland Nov 2010 Talk: Unit Testing

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