SlideShare a Scribd company logo
1 of 22
TDD in Python “Why”, but mostly “how”
Hi, I’m Tudor Pythonista Odeon Consulting Group Pte Ltd – www.od-eon.com Grok Media Pte Ltd – www.grokprojects.com Developing 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 Diamond http://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 ,[object Object]
 archives
 etc.,[object Object]
In Python file handling: ,[object Object]
 PIL for images
zipfile for archive
pisa for .pdf
 plethora of other libs for various filetype,[object Object]
models.FileField()
models.ImageField()
ImageKit for file processing http://bit.ly/django-imagekit ,[object Object]
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')
Django classProfileTest(TestCase): deftearDown(self): for profile inProfile.objects.all(): profile.delete(); Python import os os.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 posting user_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 plans left_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 exists tmp_dir = os.path.join(settings.MEDIA_ROOT, 'tmp') if not os.path.isdir(tmp_dir): os.makedirs(tmp_dir) # create the book object b = Book(title = file_name, original = filedata, path = folder_name, user = user, organisation = org) b.save()             #send the pdf file for processing ConvertBook.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))

More Related Content

What's hot

jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentationguestcf600a
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateKiev ALT.NET
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQueryGunjan Kumar
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuerymanugoel2003
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutesSimon Willison
 
jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009Remy Sharp
 
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learnedMoving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learnedBaldur Rensch
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 
Building High Performance Web Applications and Sites
Building High Performance Web Applications and SitesBuilding High Performance Web Applications and Sites
Building High Performance Web Applications and Sitesgoodfriday
 
Stack Overflow Austin - jQuery for Developers
Stack Overflow Austin - jQuery for DevelopersStack Overflow Austin - jQuery for Developers
Stack Overflow Austin - jQuery for DevelopersJonathan Sharp
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonfRafael Dohms
 

What's hot (15)

jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentation
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicate
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Crafting [Better] API Clients
Crafting [Better] API ClientsCrafting [Better] API Clients
Crafting [Better] API Clients
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Jquery-overview
Jquery-overviewJquery-overview
Jquery-overview
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009jQuery Loves Developers - Oredev 2009
jQuery Loves Developers - Oredev 2009
 
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learnedMoving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
Moving a high traffic ZF1 Enterprise Application to SF2 - Lessons learned
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
JQuery introduction
JQuery introductionJQuery introduction
JQuery introduction
 
Building High Performance Web Applications and Sites
Building High Performance Web Applications and SitesBuilding High Performance Web Applications and Sites
Building High Performance Web Applications and Sites
 
Stack Overflow Austin - jQuery for Developers
Stack Overflow Austin - jQuery for DevelopersStack Overflow Austin - jQuery for Developers
Stack Overflow Austin - jQuery for Developers
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
 

Viewers also liked

Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...Timo Stollenwerk
 
unittest in 5 minutes
unittest in 5 minutesunittest in 5 minutes
unittest in 5 minutesRay Toal
 
Test Driven Development for Embedded C
Test Driven Development for Embedded CTest Driven Development for Embedded C
Test Driven Development for Embedded CJames Grenning
 
TDD er død. Lenge leve TDD!
TDD er død. Lenge leve TDD!TDD er død. Lenge leve TDD!
TDD er død. Lenge leve TDD!Kjetil Klaussen
 
Tdd with python unittest for embedded c
Tdd with python unittest for embedded cTdd with python unittest for embedded c
Tdd with python unittest for embedded cBenux Wei
 
TDD Performance Kata
TDD Performance KataTDD Performance Kata
TDD Performance KataAndrei Savu
 

Viewers also liked (10)

Presentation TDD in Python
Presentation TDD in PythonPresentation TDD in Python
Presentation TDD in Python
 
Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...
 
Pyunit
PyunitPyunit
Pyunit
 
unittest in 5 minutes
unittest in 5 minutesunittest in 5 minutes
unittest in 5 minutes
 
Test Driven Development for Embedded C
Test Driven Development for Embedded CTest Driven Development for Embedded C
Test Driven Development for Embedded C
 
TDD er død. Lenge leve TDD!
TDD er død. Lenge leve TDD!TDD er død. Lenge leve TDD!
TDD er død. Lenge leve TDD!
 
Tdd with python unittest for embedded c
Tdd with python unittest for embedded cTdd with python unittest for embedded c
Tdd with python unittest for embedded c
 
Python unittest
Python unittestPython unittest
Python unittest
 
Python Programming Essentials - M39 - Unit Testing
Python Programming Essentials - M39 - Unit TestingPython Programming Essentials - M39 - Unit Testing
Python Programming Essentials - M39 - Unit Testing
 
TDD Performance Kata
TDD Performance KataTDD Performance Kata
TDD Performance Kata
 

Similar to PyCon APAC - Django Test Driven Development

PyCon India 2010 Building Scalable apps using appengine
PyCon India 2010 Building Scalable apps using appenginePyCon India 2010 Building Scalable apps using appengine
PyCon India 2010 Building Scalable apps using appenginePranav Prakash
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised contentMichael Peacock
 
Django tech-talk
Django tech-talkDjango tech-talk
Django tech-talkdtdannen
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Djangofool2nd
 
Django Introduction Osscamp Delhi September 08 09 2007 Mir Nazim
Django Introduction Osscamp Delhi September 08 09 2007 Mir NazimDjango Introduction Osscamp Delhi September 08 09 2007 Mir Nazim
Django Introduction Osscamp Delhi September 08 09 2007 Mir NazimMir Nazim
 
Mongo and Harmony
Mongo and HarmonyMongo and Harmony
Mongo and HarmonySteve Smith
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using DjangoNathan Eror
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonPython Ireland
 
Django O/R Mapper
Django O/R MapperDjango O/R Mapper
Django O/R MapperIan Lewis
 
Powerful Generic Patterns With Django
Powerful Generic Patterns With DjangoPowerful Generic Patterns With Django
Powerful Generic Patterns With DjangoEric Satterwhite
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJoaquim Rocha
 
12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocratJonathan Linowes
 
Solving performance issues in Django ORM
Solving performance issues in Django ORMSolving performance issues in Django ORM
Solving performance issues in Django ORMSian Lerk Lau
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBMongoDB
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)MongoSF
 
Django Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksDjango Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksShawn Rider
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in PythonBen James
 

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

PyCon India 2010 Building Scalable apps using appengine
PyCon India 2010 Building Scalable apps using appenginePyCon India 2010 Building Scalable apps using appengine
PyCon India 2010 Building Scalable apps using appengine
 
Django
DjangoDjango
Django
 
Django
DjangoDjango
Django
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised content
 
Django tech-talk
Django tech-talkDjango tech-talk
Django tech-talk
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Django
 
Django Introduction Osscamp Delhi September 08 09 2007 Mir Nazim
Django Introduction Osscamp Delhi September 08 09 2007 Mir NazimDjango Introduction Osscamp Delhi September 08 09 2007 Mir Nazim
Django Introduction Osscamp Delhi September 08 09 2007 Mir Nazim
 
Mongo and Harmony
Mongo and HarmonyMongo and Harmony
Mongo and Harmony
 
Building a Dynamic Website Using Django
Building a Dynamic Website Using DjangoBuilding a Dynamic Website Using Django
Building a Dynamic Website Using Django
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in Python
 
Django O/R Mapper
Django O/R MapperDjango O/R Mapper
Django O/R Mapper
 
Powerful Generic Patterns With Django
Powerful Generic Patterns With DjangoPowerful Generic Patterns With Django
Powerful Generic Patterns With Django
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat12 core technologies you should learn, love, and hate to be a 'real' technocrat
12 core technologies you should learn, love, and hate to be a 'real' technocrat
 
Solving performance issues in Django ORM
Solving performance issues in Django ORMSolving performance issues in Django ORM
Solving performance issues in Django ORM
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDB
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)
 
Django Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, TricksDjango Forms: Best Practices, Tips, Tricks
Django Forms: Best Practices, Tips, Tricks
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in Python
 

Recently uploaded

The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 

Recently uploaded (20)

The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 

PyCon APAC - Django Test Driven Development

  • 1. TDD in Python “Why”, but mostly “how”
  • 2. Hi, I’m Tudor Pythonista Odeon Consulting Group Pte Ltd – www.od-eon.com Grok Media Pte Ltd – www.grokprojects.com Developing 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 Diamond http://bit.ly/python-tdd
  • 4. Story of a test
  • 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.
  • 9.
  • 10.
  • 11. PIL for images
  • 14.
  • 17.
  • 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')
  • 19. Django classProfileTest(TestCase): deftearDown(self): for profile inProfile.objects.all(): profile.delete(); Python import os os.remove(path)
  • 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 posting user_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 plans left_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 exists tmp_dir = os.path.join(settings.MEDIA_ROOT, 'tmp') if not os.path.isdir(tmp_dir): os.makedirs(tmp_dir) # create the book object b = Book(title = file_name, original = filedata, path = folder_name, user = user, organisation = org) b.save() #send the pdf file for processing ConvertBook.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))
  • 22.
  • 23.
  • 25. hard to change
  • 26.
  • 27. def test_accepting_item(self): item = _create_item(self) user = User.objects.create_user('john', 'john@son.com', '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 = 10 item.minimum_for_item = 5 item.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%s@son.com' % 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 payed self.assertEquals(item.count_sold(), 10) # item buy page should be off limits now resp = 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 = 'cheryl@cole.com', 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 page resp = self.client.get(reverse('pay_item', args = [buyer.id])) #print resp.content # check the thank you page resp = self.client.get(reverse('thank_you', args = [item.id])) self.assertContains(resp, 'Thank You') self.assertContains(resp, item.count_items_left()) tests.py
  • 28.
  • 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 time! tudor.munteanu@od-eon.com tudor@grokprojects.com twitter.com/tudorizer