SlideShare a Scribd company logo
TDD in Python“Why”, but mostly “how”
Hi, I’m TudorPythonistaOdeon Consulting Group Pte Ltd – www.od-eon.comGrok Media Pte Ltd – www.grokprojects.comDeveloping web applications in Django (because it's awesome!),but mostly because it's Python.
"Test-driven development is not about testing. Test-driven development is about development (and design), specifically improving the quality and design of code. The resulting unit tests are just an extremely useful by-product.”by Jason Diamondhttp://bit.ly/python-tdd
Story of a test
# create a generic user (Steve is born)# add this user to the business group (he becomes a business owner)# create an Organisation# set permision for the organisation# Steve becomes part of the organisation# Steve defines a start and end date for the contest# Steve creates a contest and check if it was saved (URL check)# check if appears in organisation admin panel (URL check)# Steve tries to score points# gotcha! The owner of the of the contest can't score points# Mary signs up# Mary tries to score# no luck. The contest is not live yet# make the contest live# Mary scores 3 times, trough the AJAX URL# Stephanie is playing too# Susan want's to play, but the contest has reached the players maximum so she can't score# Mary, being a simple-minded user, shouldn't have access to the contest list page (URL permissions check)extracted from the code-base of Grokking.it, http://grokking.it/
It’s important to test what users can and can NOT do, otherwise you might be surprised by loopholes in the logic.
Testing Files images, media content
 archives
 etc.
In Python file handling: built-in file-handling
 PIL for images
zipfile for archive
pisa for .pdf
 plethora of other libs for various filetypeIn Django file handling: files are associated with database entries
models.FileField()
models.ImageField()
ImageKit for file processing http://bit.ly/django-imagekit def_get_image_for_model(path):    """    returns SimpleUploadedFile from a `path`.     Reads mimetype and filecontent    """fromdjango.core.files.uploadedfileimportSimpleUploadedFileimport mimetypesas mimeim = open(path)c = im.read()im.close()m = mime.guess_type(path)uf = SimpleUploadedFile(path, c, m)return uf
image_path = settings.MEDIA_ROOT + 'testdata/luke.png'image = _get_image_for_model(image_path)megan_fox =Hero.objects.create(name =’Luke Skywalker', image = 									image, movie =’Star Wars')
DjangoclassProfileTest(TestCase):deftearDown(self):for profile inProfile.objects.all():profile.delete();Pythonimport osos.remove(path)
TDD for better, faster and leaner apps
def _upload_file(request):    """    Upload file to the server.    """ if request.method == 'POST':        #print request.POST        #get the user who is postinguser_id = request.POST.get('check')        user = User.objects.get(pk=user_id)        title = request.POST.get('title')if not user.get_profile().is_business:print "404 Reason: Not a business user!"raise Http404()        # check the number of uploaded books vs plansleft_catalogs = left_books(user)        if left_catalogs <= 0:print "404 Reason: user reached plan's catalog number limit"raise Http404()        folder = request.POST.get('folder')if request.FILES:filedata = request.FILES['Filedata']file_name, file_ext = os.path.splitext(filedata.name)            #file_name, file_ext = filedata.name.split('.') #might need improvment for pdf files with . in names            # folder name is the organisation slug            org = getUsersOrganisation(user)if not org:print "404 Reason: The user is not a member of an Organisation"raise Http404()folder_name = os.path.join(org.slug, file_name)             # Check if tmp existstmp_dir = os.path.join(settings.MEDIA_ROOT, 'tmp')if not os.path.isdir(tmp_dir):os.makedirs(tmp_dir)# create the book objectb = Book(title = file_name, original = filedata, path = folder_name, user = user, organisation = org)b.save()            #send the pdf file for processingConvertBook.objects.create(book=b)            #print b.pk    # This is the tricky part, we need to send a response str back to the flash object    # to trigger the onComplete function.return HttpResponse(str(b.pk))
PyCon APAC - Django Test Driven Development

More Related Content

What's hot (15)

PDF
jQuery%20on%20Rails%20Presentation
guestcf600a
 
PPT
Micro-ORM Introduction - Don't overcomplicate
Kiev ALT.NET
 
PPTX
Introduction to jQuery
Gunjan Kumar
 
PDF
Crafting [Better] API Clients
Wellfire Interactive
 
ODP
Drupal Best Practices
manugoel2003
 
ODP
Introduction to jQuery
manugoel2003
 
PPTX
Jquery-overview
Isfand yar Khan
 
PDF
Learning jQuery in 30 minutes
Simon Willison
 
PDF
jQuery Loves Developers - Oredev 2009
Remy Sharp
 
PDF
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Baldur Rensch
 
PDF
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
PPT
JQuery introduction
NexThoughts Technologies
 
PPTX
Building High Performance Web Applications and Sites
goodfriday
 
PDF
Stack Overflow Austin - jQuery for Developers
Jonathan Sharp
 
PDF
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
Rafael Dohms
 
jQuery%20on%20Rails%20Presentation
guestcf600a
 
Micro-ORM Introduction - Don't overcomplicate
Kiev ALT.NET
 
Introduction to jQuery
Gunjan Kumar
 
Crafting [Better] API Clients
Wellfire Interactive
 
Drupal Best Practices
manugoel2003
 
Introduction to jQuery
manugoel2003
 
Jquery-overview
Isfand yar Khan
 
Learning jQuery in 30 minutes
Simon Willison
 
jQuery Loves Developers - Oredev 2009
Remy Sharp
 
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Baldur Rensch
 
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
JQuery introduction
NexThoughts Technologies
 
Building High Performance Web Applications and Sites
goodfriday
 
Stack Overflow Austin - jQuery for Developers
Jonathan Sharp
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
Rafael Dohms
 

Viewers also liked (10)

PDF
Presentation TDD in Python
Roberto Bettazzoni
 
PDF
Python-nose: A unittest-based testing framework for Python that makes writing...
Timo Stollenwerk
 
ODP
Pyunit
Ikuru Kanuma
 
PPTX
unittest in 5 minutes
Ray Toal
 
PDF
Test Driven Development for Embedded C
James Grenning
 
PPTX
TDD er død. Lenge leve TDD!
Kjetil Klaussen
 
PDF
Tdd with python unittest for embedded c
Benux Wei
 
PDF
Python unittest
Felipe Ruhland
 
PPTX
Python Programming Essentials - M39 - Unit Testing
P3 InfoTech Solutions Pvt. Ltd.
 
PDF
TDD Performance Kata
Andrei Savu
 
Presentation TDD in Python
Roberto Bettazzoni
 
Python-nose: A unittest-based testing framework for Python that makes writing...
Timo Stollenwerk
 
Pyunit
Ikuru Kanuma
 
unittest in 5 minutes
Ray Toal
 
Test Driven Development for Embedded C
James Grenning
 
TDD er død. Lenge leve TDD!
Kjetil Klaussen
 
Tdd with python unittest for embedded c
Benux Wei
 
Python unittest
Felipe Ruhland
 
Python Programming Essentials - M39 - Unit Testing
P3 InfoTech Solutions Pvt. Ltd.
 
TDD Performance Kata
Andrei Savu
 
Ad

Similar to PyCon APAC - Django Test Driven Development (20)

PDF
Django Good Practices
Solution4Future
 
PPTX
E-Bazaar
ayanthi1
 
PPTX
Meetup django common_problems(1)
Eric Satterwhite
 
PPT
JBUG 11 - Django-The Web Framework For Perfectionists With Deadlines
Tikal Knowledge
 
PPT
Rotzy - Building an iPhone Photo Sharing App on Google App Engine
geehwan
 
KEY
Setting a baseline for your django projects
Gary Reynolds
 
PDF
Django - basics
University of Technology
 
ODP
Pruebas unitarias con django
Tomás Henríquez
 
PDF
Django
Mohamed Ramadan
 
KEY
Introduction to Django
James Casey
 
PPT
Django Forms: Best Practices, Tips, Tricks
Shawn Rider
 
PDF
Programmers slang
bocribbz
 
PDF
Django design-patterns
Agiliq Info Solutions India Pvt Ltd
 
KEY
Intro To Django
Udi Bauman
 
PDF
Python RESTful webservices with Python: Flask and Django solutions
Solution4Future
 
PPTX
Gae
guest0e51364
 
PPTX
RESTful APIs: Promises & lies
Tareque Hossain
 
PDF
Django Overview
Brian Tol
 
PDF
Deep-dive into Django #1
Avik Das
 
PDF
Distributed and Cloud Computing 1st Edition Hwang Solutions Manual
hosleadamsfy
 
Django Good Practices
Solution4Future
 
E-Bazaar
ayanthi1
 
Meetup django common_problems(1)
Eric Satterwhite
 
JBUG 11 - Django-The Web Framework For Perfectionists With Deadlines
Tikal Knowledge
 
Rotzy - Building an iPhone Photo Sharing App on Google App Engine
geehwan
 
Setting a baseline for your django projects
Gary Reynolds
 
Django - basics
University of Technology
 
Pruebas unitarias con django
Tomás Henríquez
 
Introduction to Django
James Casey
 
Django Forms: Best Practices, Tips, Tricks
Shawn Rider
 
Programmers slang
bocribbz
 
Django design-patterns
Agiliq Info Solutions India Pvt Ltd
 
Intro To Django
Udi Bauman
 
Python RESTful webservices with Python: Flask and Django solutions
Solution4Future
 
RESTful APIs: Promises & lies
Tareque Hossain
 
Django Overview
Brian Tol
 
Deep-dive into Django #1
Avik Das
 
Distributed and Cloud Computing 1st Edition Hwang Solutions Manual
hosleadamsfy
 
Ad

Recently uploaded (20)

PDF
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
PDF
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
PPTX
Digital Circuits, important subject in CS
contactparinay1
 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
PDF
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PDF
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
PDF
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
PDF
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PPT
Ericsson LTE presentation SEMINAR 2010.ppt
npat3
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
PDF
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
PPTX
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
Digital Circuits, important subject in CS
contactparinay1
 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Ericsson LTE presentation SEMINAR 2010.ppt
npat3
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 

PyCon APAC - Django Test Driven Development

  • 1. TDD in Python“Why”, but mostly “how”
  • 2. Hi, I’m TudorPythonistaOdeon Consulting Group Pte Ltd – www.od-eon.comGrok Media Pte Ltd – www.grokprojects.comDeveloping web applications in Django (because it's awesome!),but mostly because it's Python.
  • 3. "Test-driven development is not about testing. Test-driven development is about development (and design), specifically improving the quality and design of code. The resulting unit tests are just an extremely useful by-product.”by Jason Diamondhttp://bit.ly/python-tdd
  • 5. # create a generic user (Steve is born)# add this user to the business group (he becomes a business owner)# create an Organisation# set permision for the organisation# Steve becomes part of the organisation# Steve defines a start and end date for the contest# Steve creates a contest and check if it was saved (URL check)# check if appears in organisation admin panel (URL check)# Steve tries to score points# gotcha! The owner of the of the contest can't score points# Mary signs up# Mary tries to score# no luck. The contest is not live yet# make the contest live# Mary scores 3 times, trough the AJAX URL# Stephanie is playing too# Susan want's to play, but the contest has reached the players maximum so she can't score# Mary, being a simple-minded user, shouldn't have access to the contest list page (URL permissions check)extracted from the code-base of Grokking.it, http://grokking.it/
  • 6. It’s important to test what users can and can NOT do, otherwise you might be surprised by loopholes in the logic.
  • 7. Testing Files images, media content
  • 10. In Python file handling: built-in file-handling
  • 11. PIL for images
  • 14. plethora of other libs for various filetypeIn Django file handling: files are associated with database entries
  • 17. ImageKit for file processing http://bit.ly/django-imagekit def_get_image_for_model(path): """ returns SimpleUploadedFile from a `path`. Reads mimetype and filecontent """fromdjango.core.files.uploadedfileimportSimpleUploadedFileimport mimetypesas mimeim = open(path)c = im.read()im.close()m = mime.guess_type(path)uf = SimpleUploadedFile(path, c, m)return uf
  • 18. image_path = settings.MEDIA_ROOT + 'testdata/luke.png'image = _get_image_for_model(image_path)megan_fox =Hero.objects.create(name =’Luke Skywalker', image = image, movie =’Star Wars')
  • 20. TDD for better, faster and leaner apps
  • 21. def _upload_file(request): """ Upload file to the server. """ if request.method == 'POST': #print request.POST #get the user who is postinguser_id = request.POST.get('check') user = User.objects.get(pk=user_id) title = request.POST.get('title')if not user.get_profile().is_business:print "404 Reason: Not a business user!"raise Http404() # check the number of uploaded books vs plansleft_catalogs = left_books(user) if left_catalogs <= 0:print "404 Reason: user reached plan's catalog number limit"raise Http404() folder = request.POST.get('folder')if request.FILES:filedata = request.FILES['Filedata']file_name, file_ext = os.path.splitext(filedata.name) #file_name, file_ext = filedata.name.split('.') #might need improvment for pdf files with . in names # folder name is the organisation slug org = getUsersOrganisation(user)if not org:print "404 Reason: The user is not a member of an Organisation"raise Http404()folder_name = os.path.join(org.slug, file_name) # Check if tmp existstmp_dir = os.path.join(settings.MEDIA_ROOT, 'tmp')if not os.path.isdir(tmp_dir):os.makedirs(tmp_dir)# create the book objectb = Book(title = file_name, original = filedata, path = folder_name, user = user, organisation = org)b.save() #send the pdf file for processingConvertBook.objects.create(book=b) #print b.pk # This is the tricky part, we need to send a response str back to the flash object # to trigger the onComplete function.return HttpResponse(str(b.pk))
  • 25. hard to change
  • 26. prone to bugs and long debugging sessionsviews.pydef buy(request, item_id = None): item = get_object_or_404(Item, id = item_id) if request.method == 'POST': form = BuyItemForm(request.POST)if form.is_valid():cd = form.cleaned_data user, profile = Profile.objects.create_user(cd) buyer = Buyer.objects.create(user = user, item = item) EmailValidation.objects.add(user = user, email = user.email)return HttpResponseRedirect(reverse('item_pay', args = [buyer.id]))else: form = BuyItemForm(initial = {'country': 'Singapore', 'city': "444"})return render_to_response('items/buy.html', locals(), context_instance=RequestContext(request))
  • 27. def test_accepting_item(self): item = _create_item(self) user = User.objects.create_user('john', '[email protected]', '123456') buyer = Buyer.objects.create(user = user, item = item)self.assertEquals(User.objects.count(), 1)self.assertEquals(Buyer.objects.count(), 1)self.assertEquals(item.buyer_set.count(), 1)self.assertEquals(item.get_percentage_sold(), 0.0) def test_max_buyers(self): item = _create_item(self)item.max_available = 10item.minimum_for_item = 5item.save()resp = self.client.get('/')self.assertContains(resp, 'more to go') for i in range(1, 12): user = User.objects.create_user('john%s' % i, 'john%[email protected]' % i, '123456') buyer = Buyer.objects.create(user = user, item = item, payed = True) if i < item.minimum_for_item:resp = self.client.get('/')self.assertContains(resp, 'more to go')elifi == item.minimum_for_item:self.assertTrue(item.minimum_reached())resp = self.client.get('/')self.assertContains(resp, 'is ON!') elifi > item.minimum_for_item and i < item.max_available:resp = self.client.get('/')self.assertContains(resp, 'is ON!')resp = self.client.get('/')self.assertContains(resp, 'Ding Ding Ding')self.assertEquals(Buyer.objects.count(), 10)self.assertEquals(Item.objects.count(), 2)self.assertTrue(item.is_closed()) # double check number of people who # bought AND payedself.assertEquals(item.count_sold(), 10) # item buy page should be off limits nowresp = self.client.get(reverse('buy_item', args = [item.id]))self.assertRedirects(resp, reverse('closed_item')) def test_fill_buy_form(self): item = _create_item(self)resp = self._get_and_check(reverse('buy_item', args = [item.id])) data = dict(email = '[email protected]', first_name = 'Cheryl', last_name = 'Cole', address = "55 Main LondongStree", zip = '123456', mobile = '12345678')resp = self.client.post(reverse('buy_item', args = [item.id]), data = data)self.assertEquals(Profile.objects.count(), 0)self.assertEquals(User.objects.count(), 0)self.assertEquals(Buyer.objects.count(), 0)data['city'] = '282'data['country'] = 'United Kingdom'resp = self.client.post(reverse('buy_item', args = [item.id]), data = data)self.assertEquals(Profile.objects.count(), 1)self.assertEquals(User.objects.count(), 1)self.assertEquals(Buyer.objects.count(), 1) self.assertEquals(User.objects.all()[0].first_name, "Cheryl") self.assertEquals(User.objects.all()[0].last_name, "Cole") buyer = Buyer.objects.all()[0]self.assertRedirects(resp, reverse('pay_item', args = [buyer.id]))self.assertEquals(len(mail.outbox), 1) # check the source of paypal redirect pageresp = self.client.get(reverse('pay_item', args = [buyer.id])) #print resp.content # check the thank you pageresp = self.client.get(reverse('thank_you', args = [item.id]))self.assertContains(resp, 'Thank You')self.assertContains(resp, item.count_items_left())tests.py
  • 29. TDD enables to write lean code. What is that? Faster to change and with a smaller chance of breaking other parts.
  • 30. Thanks for your [email protected]@grokprojects.comtwitter.com/tudorizer