Book description
By taking you through the development of a real web application from beginning to end, the second edition of this hands-on guide demonstrates the practical advantages of test-driven development (TDD) with Python. You’ll learn how to write and run tests before building each part of your app, and then develop the minimum amount of code required to pass those tests. The result? Clean code that works.
In the process, you’ll learn the basics of Django, Selenium, Git, jQuery, and Mock, along with current web development techniques. If you’re ready to take your Python skills to the next level, this book—updated for Python 3.6—clearly demonstrates how TDD encourages simple designs and inspires confidence.
- Dive into the TDD workflow, including the unit test/code cycle and refactoring
- Use unit tests for classes and functions, and functional tests for user interactions within the browser
- Learn when and how to use mock objects, and the pros and cons of isolated vs. integrated tests
- Test and automate your deployments with a staging server
- Apply tests to the third-party plugins you integrate into your site
- Run tests automatically by using a Continuous Integration environment
- Use TDD to build a REST API with a front-end Ajax interface
Publisher resources
Table of contents
- Preface
- Prerequisites and Assumptions
- Companion Video
- Acknowledgments
- I. The Basics of TDD and Django
- 1. Getting Django Set Up Using a Functional Test
- 2. Extending Our Functional Test Using the unittest Module
- 3. Testing a Simple Home Page with Unit Tests
- 4. What Are We Doing with All These Tests? (And, Refactoring)
-
5. Saving User Input: Testing the Database
- Wiring Up Our Form to Send a POST Request
- Processing a POST Request on the Server
- Passing Python Variables to Be Rendered in the Template
- Three Strikes and Refactor
- The Django ORM and Our First Model
- Saving the POST to the Database
- Redirect After a POST
- Rendering Items in the Template
- Creating Our Production Database with migrate
- Recap
- 6. Improving Functional Tests: Ensuring Isolation and Removing Voodoo Sleeps
-
7. Working Incrementally
- Small Design When Necessary
- Implementing the New Design Incrementally Using TDD
- Ensuring We Have a Regression Test
- Iterating Towards the New Design
- Taking a First, Self-Contained Step: One New URL
- Green? Refactor
- Another Small Step: A Separate Template for Viewing Lists
- A Third Small Step: A URL for Adding List Items
- Biting the Bullet: Adjusting Our Models
- Each List Should Have Its Own URL
- The Functional Tests Detect Another Regression
- One More View to Handle Adding Items to an Existing List
- A Final Refactor Using URL includes
- II. Web Development Sine Qua Nons
-
8. Prettification: Layout and Styling, and What to Test About It
- What to Functionally Test About Layout and Style
- Prettification: Using a CSS Framework
- Django Template Inheritance
- Integrating Bootstrap
- Static Files in Django
- Using Bootstrap Components to Improve the Look of the Site
- Using Our Own CSS
- What We Glossed Over: collectstatic and Other Static Directories
- A Few Things That Didn’t Make It
-
9. Testing Deployment Using a Staging Site
- TDD and the Danger Areas of Deployment
- As Always, Start with a Test
- Getting a Domain Name
- Manually Provisioning a Server to Host Our Site
- Deploying Our Code Manually
- Debugging a Deployment That Doesn’t Seem to Work at All
- Hacking ALLOWED_HOSTS in settings.py
- Creating the Database with migrate
- Success! Our Hack Deployment Works
-
10. Getting to a Production-Ready Deployment
- What We Need to Do
- Switching to Nginx
- Switching to Gunicorn
- Getting Nginx to Serve Static Files
- Switching to Using Unix Sockets
- Using Environment Variables to Adjust Settings for Production
- Essential Googling the Error Message
- Using a .env File to Store Our Environment Variables
- Using Systemd to Make Sure Gunicorn Starts on Boot
- Thinking About Automating
- Saving Our Progress
- 11. Automating Deployment with Fabric
- 12. Splitting Our Tests into Multiple Files, and a Generic Wait Helper
- 13. Validation at the Database Layer
- 14. A Simple Form
- 15. More Advanced Forms
-
16. Dipping Our Toes, Very Tentatively,
into JavaScript
- Starting with an FT
- Setting Up a Basic JavaScript Test Runner
- Using jQuery and the Fixtures Div
- Building a JavaScript Unit Test for Our Desired Functionality
- Fixtures, Execution Order, and Global State: Key Challenges of JS Testing
- Columbo Says: Onload Boilerplate and Namespacing
- JavaScript Testing in the TDD Cycle
- A Few Things That Didn’t Make It
- 17. Deploying Our New Code
- III. More Advanced Topics in Testing
- 18. User Authentication, Spiking, and De-Spiking
-
19. Using Mocks to Test External Dependencies or Reduce Duplication
- Before We Start: Getting the Basic Plumbing In
- Mocking Manually, aka Monkeypatching
- The Python Mock Library
- De-spiking Our Custom Authentication Backend
- An Alternative Reason to Use Mocks: Reducing Duplication
- The Moment of Truth: Will the FT Pass?
- It Works in Theory! Does It Work in Practice?
- Finishing Off Our FT, Testing Logout
- 20. Test Fixtures and a Decorator for Explicit Waits
- 21. Server-Side Debugging
-
22. Finishing “My Lists”: Outside-In TDD
- The Alternative: “Inside-Out”
- Why Prefer “Outside-In”?
- The FT for “My Lists”
- The Outside Layer: Presentation and Templates
- Moving Down One Layer to View Functions (the Controller)
- Another Pass, Outside-In
- The Next “Requirement” from the Views Layer: New Lists Should Record Owner
- Moving Down to the Model Layer
-
23. Test Isolation, and “Listening to Your Tests”
- Revisiting Our Decision Point: The Views Layer Depends on Unwritten Models Code
- A First Attempt at Using Mocks for Isolation
- Listen to Your Tests: Ugly Tests Signal a Need to Refactor
- Rewriting Our Tests for the View to Be Fully Isolated
- Moving Down to the Forms Layer
- Finally, Moving Down to the Models Layer
- The Moment of Truth (and the Risks of Mocking)
- Thinking of Interactions Between Layers as “Contracts”
- One More Test
- Tidy Up: What to Keep from Our Integrated Test Suite
- Conclusions: When to Write Isolated Versus Integrated Tests
- 24. Continuous Integration (CI)
- 25. The Token Social Bit, the Page Pattern, and an Exercise for the Reader
- 26. Fast Tests, Slow Tests, and Hot Lava
- Obey the Testing Goat!
- A. PythonAnywhere
- B. Django Class-Based Views
- C. Provisioning with Ansible
- D. Testing Database Migrations
-
E. Behaviour-Driven Development (BDD)
- What Is BDD?
- Basic Housekeeping
- Writing an FT as a “Feature” Using Gherkin Syntax
- Coding the Step Functions
- First Step Definition
- setUp and tearDown Equivalents in environment.py
- Another Run
- Capturing Parameters in Steps
- Comparing the Inline-Style FT
- BDD Encourages Structured Test Code
- The Page Pattern as an Alternative
- BDD Might Be Less Expressive than Inline Comments
- Will Nonprogrammers Write Tests?
- Some Tentative Conclusions
-
F. Building a REST API: JSON, Ajax, and Mocking with JavaScript
- Our Approach for This Appendix
- Choosing Our Test Approach
- Basic Piping
- Actually Responding with Something
- Adding POST
- Testing the Client-Side Ajax with Sinon.js
- Wiring It All Up in the Template to See If It Really Works
- Implementing Ajax POST, Including the CSRF Token
- Mocking in JavaScript
- Data Validation: An Exercise for the Reader?
- G. Django-Rest-Framework
- H. Cheat Sheet
-
I. What to Do Next
- Notifications—Both on the Site and by Email
- Switch to Postgres
- Run Your Tests Against Different Browsers
- 404 and 500 Tests
- The Django Admin Site
- Write Some Security Tests
- Test for Graceful Degradation
- Caching and Performance Testing
- JavaScript MVC Frameworks
- Async and Websockets
- Switch to Using py.test
- Check Out coverage.py
- Client-Side Encryption
- Your Suggestion Here
- J. Source Code Examples
- Bibliography
- Index
Product information
- Title: Test-Driven Development with Python, 2nd Edition
- Author(s):
- Release date: August 2017
- Publisher(s): O'Reilly Media, Inc.
- ISBN: 9781491958650
You might also like
book
Fluent Python, 2nd Edition
Don't waste time bending Python to fit patterns you've learned in other languages. Python's simplicity lets …
book
Head First Python, 2nd Edition
Want to learn the Python language without slogging your way through how-to manuals? With Head First …
book
Using Asyncio in Python
If you’re among the Python developers put off by asyncio’s complexity, it’s time to take another …
book
Python Crash Course, 3rd Edition
Python Crash Course is the world's best-selling guide to the Python guide programming language, with over …