O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Test-Driven Python Development

Book Description

Develop high-quality and maintainable Python applications using the principles of test-driven development

In Detail

This book starts with a look at the test-driven development process, and how it is different from the traditional way of writing code. All the concepts are presented in the context of a real application that is developed in a step-by-step manner over the course of the book. While exploring the common types of smelly code, we will go back into our example project and clean up the smells that we find.

Additionally, we will use mocking to implement the parts of our example project that depend on other systems. Towards the end of the book, we'll take a look at the most common patterns and anti-patterns associated with test-driven development, including integration of test results into the development process.

What You Will Learn

  • Implement the test-driven development process in Python applications
  • Fully leverage Python's powerful built-in unittest and doctest modules
  • Effectively add features to existing code bases that do not have any tests
  • Safely resolve problems with the code and design, without breaking any functionality
  • Utilize Python's powerful mock and patch functionality to test complex interactions
  • Integrate unit testing into the overall software delivery process
  • Use doctest to test code with examples
  • Enhance TDD with the nose2 test runner

Downloading the example code for this book. You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.

Table of Contents

  1. Test-Driven Python Development
    1. Table of Contents
    2. Test-Driven Python Development
    3. Credits
    4. About the Author
    5. Acknowledgments
    6. About the Reviewers
    7. www.PacktPub.com
      1. Support files, eBooks, discount offers, and more
        1. Why subscribe?
        2. Free access for Packt account holders
    8. Preface
      1. What this book covers
      2. What you need for this book
      3. Who this book is for
      4. Conventions
      5. Reader feedback
      6. Customer support
        1. Downloading the example code
        2. Errata
        3. Piracy
        4. Questions
    9. 1. Getting Started with Test-Driven Development
      1. Prerequisites
      2. Understanding test-driven development
        1. TDD versus unit testing versus integration testing
      3. Using TDD to build a stock alert application
        1. Writing our first test
        2. Analyzing the test output
        3. Test errors versus test failures
        4. Making the test pass
      4. Reorganizing the test code
        1. Running the tests after the reorganization
      5. Summary
    10. 2. Red-Green-Refactor – The TDD Cycle
      1. Tests are executable requirements
      2. Arrange-Act-Assert
      3. Documenting our tests
      4. Testing for exceptions
      5. Exploring assert methods
      6. Specific asserts versus generic asserts
      7. Setup and teardown
      8. Brittle tests
      9. Refactoring the design
      10. Refactoring tests
      11. Exploring the Rule classes
      12. Exercise
      13. Summary
    11. 3. Code Smells and Refactoring
      1. A dual crossover moving average
      2. Implementing the dual crossover moving average
      3. Identifying code smells
      4. Refactoring
        1. The Rename Variable and Rename Method refactorings
        2. Commenting Styles
        3. Replace Magic Literals with Constants
        4. The Extract Method refactoring
        5. Replace Calculation with Temporary Variable
        6. Extract Conditional to Method
        7. The DRY principle
        8. Single Responsibility Principle
        9. Extract Class
        10. Move Method to Class
      5. The importance of tests
      6. Exercise
      7. Wrapping up
      8. Summary
    12. 4. Using Mock Objects to Test Interactions
      1. Hand writing a simple mock
      2. Using the Python mocking framework
        1. Mocking objects
        2. Mocking return values
        3. Mocking side effects
        4. How much mocking is too much?
        5. Mocks versus stubs versus fakes versus spies
        6. Patching methods
          1. An important gotcha when patching
      3. Tying it all together
      4. Summary
    13. 5. Working with Legacy Code
      1. What is legacy code?
      2. Understanding the code
        1. What are characterization tests?
        2. Using the Python interactive shell to understand the code
        3. Writing a characterization test
        4. Using pdb to understand the code
        5. Some common pdb commands
        6. Walking through a pdb session
      3. Techniques to break dependencies
        1. The Rope refactoring library
        2. Separate initialization from execution
        3. Use default values for parameters
        4. Extract the method and test
        5. Inject dependencies
        6. Inherit and test
        7. Stubbing local methods
        8. Extract the method and stub
      4. The cycle continues
      5. Time to refactor
        1. Long-term refactoring
      6. Summary
    14. 6. Maintaining Your Test Suite
      1. Goals of test maintenance
      2. Organizing tests
        1. Filesystem layout
        2. Naming conventions
        3. Test suite grouping
      3. Making tests readable
        1. Using docstrings
        2. Using fixtures
        3. Fixtures and patching
        4. Using a custom test case class hierarchy
      4. Writing tests closer to the domain
        1. Writing helper methods
        2. Writing better asserts
        3. Using custom equality checkers
        4. Using matchers
      5. Summary
    15. 7. Executable Documentation with doctest
      1. Our first doctest
        1. Running the doctest
      2. Test failures
      3. Testing for exceptions
      4. Package-level doctests
      5. Maintaining doctests
        1. Running a suite of doctests
        2. Setup and teardown
      6. Limitations of doctest
        1. Doctest directives
      7. How do doctests fit into the TDD process?
      8. Summary
    16. 8. Extending unittest with nose2
      1. Getting started with nose2
      2. Writing tests for nose2
        1. Setup and teardown
        2. Parameterized tests
        3. Generated tests
        4. Layers
      3. nose2 plugins
        1. Doctest support
        2. Writing test results to an XML file
        3. Measuring test coverage
        4. Debugging test failures
          1. nose2 configuration
      4. Summary
    17. 9. Unit Testing Patterns
      1. Pattern – fast tests
      2. Pattern – running a subset of tests
        1. Test loaders
        2. Using the load_tests protocol
        3. Skipping tests
      3. Pattern – using attributes
        1. Attributes with vanilla unittests
      4. Pattern – expected failures
      5. Pattern – data-driven tests
      6. Pattern – integration and system tests
      7. Pattern – spies
        1. Pattern – asserting a sequence of calls
        2. Pattern – patching the open function
        3. Pattern – mocking with mutable args
      8. Summary
    18. 10. Tools to Improve Test-Driven Development
      1. TDD tools
        1. py.test
          1. py.test versus nose2
        2. Trial
        3. Sure
        4. PyHamcrest
      2. Integrating with build tools
        1. Paver
      3. Integrating with packaging tools
        1. Setuptools
      4. Distutils
      5. Integrating with continuous integration tools
        1. Jenkins
        2. Travis CI
      6. Other tools
        1. tox
        2. Sphinx
      7. IDE integration
      8. Summary
    19. A. Answers to Exercises
      1. Red-Green-Refactor – The TDD Cycle
      2. Code Smells and Refactoring
    20. B. Working with Older Python Versions
      1. Writing code that is compatible across versions
      2. Running tests from the command line
      3. Running the examples in this book
    21. Index