Top Banner
How to Write Fast and Efficient Unit Tests in Django Casey Kinsey DjangoCon 2013 Monday, September 2, 13
30

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

Jan 15, 2015

Download

Technology

Casey Kinsey

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: DjangoCon 2013 - How to Write Fast and Efficient Unit Tests in Django

How to Write Fast and Efficient Unit Tests in DjangoCasey KinseyDjangoCon 2013

Monday, September 2, 13

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

A REAL NEED FOR TEST SPEED

Monday, September 2, 13

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

A REAL NEED FOR TEST 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

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

WHY SHOULD I BE CONCERNED WITH UNIT TEST 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

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

•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

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

THE FIRST STEP TO FASTER UNIT TESTS:WRITE UNIT TESTS

Monday, September 2, 13

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

UNIT TESTS VS INTEGRATION TESTS

•Many Django project test suites are comprised mostly of integration tests

•What is a Unit Test?

•Unit Tests cover a small “unit” of code

• Ideally, these units include as few branches as possible

•What is an Integration Test?

• Integration Tests test the contracts between your “units”

Monday, September 2, 13

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

UNIT TESTS VS INTEGRATION TESTS

•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

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

UNIT TESTS VS INTEGRATION TESTS

• A good unit tests covers code that is limited in functionality/scope

• Ideally, a single method with limited external calls

Monday, September 2, 13

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

UNIT TESTS VS INTEGRATION TESTS

• 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

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

SET UP CAUTIOUSLY

Monday, September 2, 13

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

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

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

Monday, September 2, 13

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

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

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

THE DATABASE IS HOT LAVA

Monday, September 2, 13

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

XKCD.COM/735/Monday, September 2, 13

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

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

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

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

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

Monday, September 2, 13

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

FAKE IT ‘TIL YOU MAKE IT WITH MOCK

Monday, September 2, 13

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

FAKE IT ‘TIL YOU 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

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

FAKE IT ‘TIL YOU 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

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

FAKE IT ‘TIL YOU 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

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

FAKE IT ‘TIL YOU MAKE IT WITH MOCK

Monday, September 2, 13

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

FAKE IT ‘TIL YOU 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: http://www.voidspace.org.uk/python/mock/

Monday, September 2, 13

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

IT’S OKAY TO ENGINEER WHEN TESTING

Monday, September 2, 13

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

IT’S OKAY TO ENGINEER WHEN TESTING

•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

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

HOW SLOW TESTING YIELDED EFFECTIVE TESTING

Monday, September 2, 13

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

HOW SLOW TESTING YIELDED EFFECTIVE TESTING

• 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

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

THANK YOU!

Casey KinseyConsultant, Celerity

Slides available online:

Internetswww.caseykinsey.com

www.celerity.com

Twitter@cordiskinsey

@CelerityITLLC

Monday, September 2, 13