SlideShare ist ein Scribd-Unternehmen logo
1 von 20
Downloaden Sie, um offline zu lesen
The Test Client
  Dr Russell Keith-Magee
     DjangoCon 2009
What is it?

• A way to build unit tests of the full stack
• Acts “kinda-sorta” like a browser
• Stateful
• Default instance on django.test.TestCase
• Can be instantiated outside test framework
The test client isn’t

• A live browser test framework
 • Selenium
 • Twill
 • Windmill
Why is it different?

• TestClient can’t do some things
 • No JavaScript
 • DOM validation or control
• Can do some things that browsers can’t
GET a page
c = TestClient()

c.get(‘/foo/’)

c.get(‘/foo/’, data={‘bar’:3})

c.get(‘/foo/?bar=3’)
Returns a response

• response.status_code
• response.content
• response.cookies
• response[‘Content-Disposition’]
... and a little more
• response.template
 • The template(s) used used in rendering
• response.context
 • The context objects used in rendering
 • response.context[‘foo’]
... and it maintains state


• self.cookies
• self.session
Login/Logout

c.login(username='foo',
        password='password')

c.logout()
POST a page
c = TestClient()

c.post(‘/foo/’)

c.post(‘/foo/?bar=3’)

c.post(‘/foo/’, data={‘bar’: 3})

c.get(‘/foo/?whiz=4’, data={‘bar’:3})
Rest of HTTP
c.put(‘/foo/’)

c.options(‘/foo/’)

c.head(‘/foo/’)

c.delete(‘/foo/’)
A common gotcha
r = self.client.get(‘/foo’)

self.assertEquals(r.status_code, 200)

FAIL Assertion Error: 301 != 200
The fix
r = self.client.get(‘/foo’,
                    follow=True)
self.assertEquals(r.status_code, 200)

response.redirect_chain
  ➡ links visited before a non-redirect was found.
Extra Headers
c = TestClient(HTTP_HOST=‘foo.com’)

c.get(‘/foo/’, HTTP_HOST=‘foo.com’)

response['X-DJANGO-TEST']
Files
c = TestClient()

f = open(‘mydata.txt’)
c.post(‘/foo/’,
    content_type=MULTIPART_CONTENT
    data = {‘file’: f})
f.close()
Assertions
• assertContains()
• assertNotContains()
• assertFormError()
• assertTemplateUsed()
• assertTemplateNotUsed()
• assertRedirects()
Advice
• Don’t rely on assertContains
 • Assertions on template content are weak
• Test at the source
 • Is the context right?
 • Are the forms correct?
• Django’s templates make this possible!
When to use TestClient

• When you need to test the full stack
 • interaction of view and middleware
• Great for testing idempotency
Interesting hack

• Use Client as a factory for Request objects
 • Ticket #9002, Snippet #963
• Then:
 • Construct a request object
 • Use to test a single view/middleware call
Fin

Weitere ähnliche Inhalte

Was ist angesagt?

C A S Sample Php
C A S Sample PhpC A S Sample Php
C A S Sample PhpJH Lee
 
Client-side Storage 
Client-side Storage Client-side Storage 
Client-side Storage Tobias Wolf
 
Knockout.js Overview
Knockout.js OverviewKnockout.js Overview
Knockout.js Overview민태 김
 

Was ist angesagt? (6)

C A S Sample Php
C A S Sample PhpC A S Sample Php
C A S Sample Php
 
Client-side Storage 
Client-side Storage Client-side Storage 
Client-side Storage 
 
4. Php MongoDB view_data
4. Php MongoDB view_data4. Php MongoDB view_data
4. Php MongoDB view_data
 
Ajax - a quick introduction
Ajax - a quick introductionAjax - a quick introduction
Ajax - a quick introduction
 
Knockout.js Overview
Knockout.js OverviewKnockout.js Overview
Knockout.js Overview
 
Django Show
Django ShowDjango Show
Django Show
 

Andere mochten auch

Introduction to django-config
Introduction to django-configIntroduction to django-config
Introduction to django-configTareque Hossain
 
State of Pinax
State of PinaxState of Pinax
State of Pinaxjtauber
 
Fighting Malnutrition with SMS and Django
Fighting Malnutrition with SMS and DjangoFighting Malnutrition with SMS and Django
Fighting Malnutrition with SMS and DjangoAndy McKay
 
Cowboy development with Django
Cowboy development with DjangoCowboy development with Django
Cowboy development with DjangoSimon Willison
 
DjangoCon 2009 Keynote
DjangoCon 2009 KeynoteDjangoCon 2009 Keynote
DjangoCon 2009 KeynoteTed Leung
 

Andere mochten auch (6)

DjangoCon09: No! Bad Pony!
DjangoCon09: No! Bad Pony!DjangoCon09: No! Bad Pony!
DjangoCon09: No! Bad Pony!
 
Introduction to django-config
Introduction to django-configIntroduction to django-config
Introduction to django-config
 
State of Pinax
State of PinaxState of Pinax
State of Pinax
 
Fighting Malnutrition with SMS and Django
Fighting Malnutrition with SMS and DjangoFighting Malnutrition with SMS and Django
Fighting Malnutrition with SMS and Django
 
Cowboy development with Django
Cowboy development with DjangoCowboy development with Django
Cowboy development with Django
 
DjangoCon 2009 Keynote
DjangoCon 2009 KeynoteDjangoCon 2009 Keynote
DjangoCon 2009 Keynote
 

Ähnlich wie DjangoCon09: The Test Client

UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013Michelangelo van Dam
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend TestingNeil Crosby
 
Using of TDD practices for Magento
Using of TDD practices for MagentoUsing of TDD practices for Magento
Using of TDD practices for MagentoIvan Chepurnyi
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013Michelangelo van Dam
 
Whatever it takes - Fixing SQLIA and XSS in the process
Whatever it takes - Fixing SQLIA and XSS in the processWhatever it takes - Fixing SQLIA and XSS in the process
Whatever it takes - Fixing SQLIA and XSS in the processguest3379bd
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и DjangoMoscowDjango
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slidesericholscher
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETBen Hall
 

Ähnlich wie DjangoCon09: The Test Client (20)

UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
 
Using of TDD practices for Magento
Using of TDD practices for MagentoUsing of TDD practices for Magento
Using of TDD practices for Magento
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013
 
Whatever it takes - Fixing SQLIA and XSS in the process
Whatever it takes - Fixing SQLIA and XSS in the processWhatever it takes - Fixing SQLIA and XSS in the process
Whatever it takes - Fixing SQLIA and XSS in the process
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
Android dev 3
Android dev 3Android dev 3
Android dev 3
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slides
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NET
 

Kürzlich hochgeladen

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 

Kürzlich hochgeladen (20)

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

DjangoCon09: The Test Client

  • 1. The Test Client Dr Russell Keith-Magee DjangoCon 2009
  • 2. What is it? • A way to build unit tests of the full stack • Acts “kinda-sorta” like a browser • Stateful • Default instance on django.test.TestCase • Can be instantiated outside test framework
  • 3. The test client isn’t • A live browser test framework • Selenium • Twill • Windmill
  • 4. Why is it different? • TestClient can’t do some things • No JavaScript • DOM validation or control • Can do some things that browsers can’t
  • 5. GET a page c = TestClient() c.get(‘/foo/’) c.get(‘/foo/’, data={‘bar’:3}) c.get(‘/foo/?bar=3’)
  • 6. Returns a response • response.status_code • response.content • response.cookies • response[‘Content-Disposition’]
  • 7. ... and a little more • response.template • The template(s) used used in rendering • response.context • The context objects used in rendering • response.context[‘foo’]
  • 8. ... and it maintains state • self.cookies • self.session
  • 9. Login/Logout c.login(username='foo', password='password') c.logout()
  • 10. POST a page c = TestClient() c.post(‘/foo/’) c.post(‘/foo/?bar=3’) c.post(‘/foo/’, data={‘bar’: 3}) c.get(‘/foo/?whiz=4’, data={‘bar’:3})
  • 12. A common gotcha r = self.client.get(‘/foo’) self.assertEquals(r.status_code, 200) FAIL Assertion Error: 301 != 200
  • 13. The fix r = self.client.get(‘/foo’, follow=True) self.assertEquals(r.status_code, 200) response.redirect_chain ➡ links visited before a non-redirect was found.
  • 14. Extra Headers c = TestClient(HTTP_HOST=‘foo.com’) c.get(‘/foo/’, HTTP_HOST=‘foo.com’) response['X-DJANGO-TEST']
  • 15. Files c = TestClient() f = open(‘mydata.txt’) c.post(‘/foo/’, content_type=MULTIPART_CONTENT data = {‘file’: f}) f.close()
  • 16. Assertions • assertContains() • assertNotContains() • assertFormError() • assertTemplateUsed() • assertTemplateNotUsed() • assertRedirects()
  • 17. Advice • Don’t rely on assertContains • Assertions on template content are weak • Test at the source • Is the context right? • Are the forms correct? • Django’s templates make this possible!
  • 18. When to use TestClient • When you need to test the full stack • interaction of view and middleware • Great for testing idempotency
  • 19. Interesting hack • Use Client as a factory for Request objects • Ticket #9002, Snippet #963 • Then: • Construct a request object • Use to test a single view/middleware call
  • 20. Fin