Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

DjangoCon 2013 - How to Write Fast and Efficient Unit Tests in Django


Published on

Published in: Technology, Education
  • Login to see the comments

DjangoCon 2013 - How to Write Fast and Efficient Unit Tests in Django

  1. 1. How to Write Fast and Efficient Unit Tests in Django Casey Kinsey DjangoCon 2013 Monday, September 2, 13
  2. 2. A REAL NEED FORTEST SPEED Monday, September 2, 13
  3. 3. A REAL NEED FORTEST SPEED • Made an initial production release of a real product for a national media company • Test coverage was not great • Started seeing regressions in subsequent releases • Decided to aggressively pursue greater test coverage • Results were successful, but one thing clear: As test coverage increased we had an acute need for faster test suites. Monday, September 2, 13
  4. 4. WHY SHOULD I BE CONCERNED WITH UNITTEST SPEED? • If you’re serious about testing, you’re serious about at least two things: • Having lots of tests • Running those tests frequently Monday, September 2, 13
  5. 5. •A slow test suite gets in the way of your testing goals because: •Developers will avoid running tests •Preparing code for integration becomes painful •Deployment speed is directly affected Monday, September 2, 13
  7. 7. UNITTESTSVS INTEGRATIONTESTS • Many Django project test suites are comprised mostly of integration tests • What is a UnitTest? • UnitTests cover a small “unit” of code • Ideally, these units include as few branches as possible • What is an IntegrationTest? • IntegrationTests test the contracts between your “units” Monday, September 2, 13
  8. 8. UNITTESTSVS INTEGRATIONTESTS • Django test client is an integration test dead giveaway • The test client covers way more than you are interested in testing • URL Routing, Request Middleware, ORM,Template Rendering, Response Middleware, etc Monday, September 2, 13
  9. 9. UNITTESTSVS INTEGRATIONTESTS • A good unit tests covers code that is limited in functionality/scope • Ideally, a single method with limited external calls Monday, September 2, 13
  10. 10. UNITTESTSVS INTEGRATIONTESTS • Establish a good ratio of unit tests to integration tests. An example may be: • for each method that contains business logic, there should exist a unit test • for each page/view/user path of your project, there should exist an integration test • YMMV Monday, September 2, 13
  11. 11. SET UP CAUTIOUSLY Monday, September 2, 13
  12. 12. SET UP CAUTIOUSLY • Be judicious about how you use setUp/tearDown • Think like middleware--do I need this for every test in this case? • One inefficient computation can cripple a large test case Monday, September 2, 13
  13. 13. Monday, September 2, 13
  14. 14. SET UP CAUTIOUSLY • Take advantage of setUpClass / tearDownClass • Runs once per test case • Effective for read-only data that is not altered by tests • Your data will persist between tests! Monday, September 2, 13
  15. 15. THE DATABASE IS HOT LAVA Monday, September 2, 13
  16. 16. XKCD.COM/735/ Monday, September 2, 13
  17. 17. THE DATABASE IS HOT LAVA • If you touch it you’ll die • Not really, but it’s one of slowest things your application will do in a unit test • Work with read-only, non persisted data • use in-memory model instances Monday, September 2, 13
  18. 18. THE DATABASE IS HOT LAVA • Avoid fixtures. Fixtures add lots of database machinery to tests • Loaded/purged between each test in a case • Fixtures don’t adapt with your data model • Schema changes will often result in test failures • Not much need for django.test.TestCase • When you do write: in-memory database (SQLite) Monday, September 2, 13
  19. 19. Monday, September 2, 13
  20. 20. FAKE IT ‘TILYOU MAKE IT WITH MOCK Monday, September 2, 13
  21. 21. FAKE IT ‘TILYOU MAKE IT WITH MOCK • Mock is a library for creating programmable stub objects • Mock objects can be configured to emulate other objects/structures • Configure specific behavior for just for testing • Gets rid of unnecessary overhead Monday, September 2, 13
  22. 22. FAKE IT ‘TILYOU MAKE IT WITH MOCK • Use mock to emulate model instances • Set the attributes you need for testing directly • Use the spec argument to give guidelines • No Model/ORM overhead Monday, September 2, 13
  23. 23. FAKE IT ‘TILYOU MAKE IT WITH MOCK • Use mock.patch to focus your tests • Patch in configurable mock objects to sys.modules • Alter the behavior of code imported elsewhere • Eliminate branches you are not interested in testing Monday, September 2, 13
  24. 24. FAKE IT ‘TILYOU MAKE IT WITH MOCK Monday, September 2, 13
  25. 25. FAKE IT ‘TILYOU MAKE IT WITH MOCK • Use mock in more complex situations • mock.patch.multiple decorator lets you patch multiple module references simultaneously • Track the way objects are used • Mock.assert_has_calls, Mock.assert_called_with • many, many more: Monday, September 2, 13
  26. 26. IT’S OKAYTO ENGINEER WHENTESTING Monday, September 2, 13
  27. 27. IT’S OKAYTO ENGINEER WHENTESTING • Don’t be afraid to invest engineering effort into your test suite • Your tests are Python code--take advantage of it! • Write tools to help you test • Leverage 3rd party tools (mock, django-nose) • Decorators, custom test runners • If you can’t test the code efficiently, refactor the code! Monday, September 2, 13
  29. 29. HOW SLOWTESTINGYIELDED EFFECTIVETESTING • Started out working towards speed • In order to write fast tests, we had to rethink how we tested • Developed an efficient test philosophy • Resulted in much more effective tests, and ultimately better code Monday, September 2, 13
  30. 30. THANKYOU! Casey Kinsey Consultant, Celerity Slides available online: Internets Twitter @cordiskinsey @CelerityITLLC Monday, September 2, 13