238
TESTING in DJANGO by Ana Balica

TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TESTING in DJANGO

by Ana Balica

Page 2: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

@anabalica

Page 3: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

POTATO

Page 4: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Django archeology

1.0

Page 5: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Django archeology

1.0 1.101.1 1.9…

Page 6: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

#2333 Add unit test framework for end-user Django applications

Page 7: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

#2333

As an added incentive, this is a feature that is present in Rails.

Add unit test framework for end-user Django applications

Page 8: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

./manage.py test

1.0

Page 9: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

./manage.py testapp.TestClass.test_method

1.0

Page 10: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TEST RUNNER

1.0

setup test environment

tests.py models.py

teardown & results

Page 11: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

1.0

get post login logout

Page 12: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

testcase

1.01.0

assert*

Redirects

(Not)Contains

FormError

Template(Not)Used

Page 13: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.1

Page 14: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

1.1

put head delete options

Page 15: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCase

1.1

TransactionTestCase

Page 16: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.1

my test

enter transaction

rollback transaction

I am a TestCase burger

Page 17: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.1

I am a TransactionTestCase.I flush the database before each test.

Page 18: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

Page 19: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

DjangoTestSuiteRunnerfrom function to class

Page 20: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

failures = test_runner(test_labels, verbosity, interactive) if failures: sys.exit(failures)

Page 21: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

failures = test_runner(test_labels, verbosity, interactive) if failures: sys.exit(failures)

Page 22: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

0success

failures = test_runner(test_labels, verbosity, interactive) if failures: sys.exit(failures)

Page 23: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

1failure

failures = test_runner(test_labels, verbosity, interactive) if failures: sys.exit(failures)

Page 24: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

42failure

failures = test_runner(test_labels, verbosity, interactive) if failures: sys.exit(failures)

Page 25: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

256success

failures = test_runner(test_labels, verbosity, interactive) if failures: sys.exit(failures)

Page 26: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

failures = TestRunner(verbosity, interactive, failfast) if failures: sys.exit(bool(failures))

Page 27: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

failures = TestRunner(verbosity, interactive, failfast) if failures: sys.exit(bool(failures))

Page 28: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

0 / 1success failure

Page 29: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

failures = TestRunner(verbosity, interactive, failfast) if failures: sys.exit(1)

1.2

256failure

Page 30: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

failures = TestRunner(verbosity, interactive, failfast) if failures: sys.exit(1)

1.2

256failure

Page 31: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

failures = TestRunner(verbosity, interactive, failfast) if failures: sys.exit(1)

1.2

256failure

Page 32: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

failures = TestRunner(verbosity, interactive, failfast) if failures: sys.exit(1)

1.2

256failure

Page 33: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

failures = TestRunner(verbosity, interactive, failfast) if failures: sys.exit(1)

1.2

256failure

Page 34: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

multiple databases

Page 35: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

multiple databases

Page 36: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

multiple databases

primary replica

Page 37: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

multiple databases

DATABASES = { 'default': { 'HOST': 'dbprimary', # ... plus other settings }, 'replica': { 'HOST': 'dbreplica', 'TEST_MIRROR': 'default', # ... plus other settings } }

Page 38: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

multiple databases

DATABASES = { 'default': { 'HOST': 'dbprimary', # ... plus other settings }, 'replica': { 'HOST': 'dbreplica', 'TEST_MIRROR': 'default', # ... plus other settings } }

Page 39: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

multiple databases

DATABASES = { 'default': { 'HOST': 'dbprimary', # ... plus other settings }, 'replica': { 'HOST': 'dbreplica', 'TEST': {

'MIRROR': 'default', }, # ... plus other settings } }

Page 40: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

multiple databases

DATABASES = { 'default': { 'HOST': 'dbprimary', # ... plus other settings }, 'replica': { 'HOST': 'dbreplica', 'TEST': {

'MIRROR': 'default', }, # ... plus other settings } }

Page 41: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

multiple databases

primary replica

Page 42: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

multiple databases

primary replica

Page 43: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.2

multiple databases

primary replica

Page 44: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.3

Page 45: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

testcase

1.01.3

assert*

QuerysetEqual

NumQueries

Page 46: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.3

RequestFactory

Client

Page 47: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.3

RequestFactory

Client

Page 48: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.3

class RequestFactory(object): def request(self, **request): return WSGIRequest(self._base_environ(**request))

Page 49: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.3

doctests=

tests + documentation

Page 50: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.3

doctests=

tests + documentation

Page 51: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.3

@skipIfDBFeature(feature)

@skipUnlessDBFeature(feature)

Page 52: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.4

Page 53: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.4

Transaction TestCase

TestCase

Page 54: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.4

Transaction TestCase

TestCase

Simple TestCase

LiveServer TestCase

Page 55: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.4

Transaction TestCase

TestCase

Simple TestCase

LiveServer TestCase

doesn’t hit the database

Page 56: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.4

Transaction TestCase

TestCase

Simple TestCase

LiveServer TestCase

doesn’t hit the database

runs an http server

Page 57: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.4

Transaction TestCase

TestCase

Simple TestCase

LiveServer TestCase

doesn’t hit the database

runs an http server

Page 58: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

Page 59: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

TEST_RUNNERimprovements

Python 3Tutorial on testingNew assertions

Page 60: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

I am a TransactionTestCase.I flush the database before each test.

Page 61: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

I am a TransactionTestCase.I flush the database before each test.

after

Page 62: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

flush

run TransactionTestCase

enter transaction

run TestCase

rollback transaction{

Page 63: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

flush

run TransactionTestCase

enter transaction

run TestCase

rollback transaction{ dirty state

Page 64: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

flush{ run TransactionTestCase

enter transaction

run TestCase

rollback transaction

Page 65: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

flush{run TransactionTestCase

enter transaction

run TestCase

rollback transaction

Page 66: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

flush{ run TransactionTestCase

enter transaction

run TestCase

rollback transaction

Page 67: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

flush{ run TransactionTestCase

enter transaction

run TestCase

rollback transaction

Page 68: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.5

flush{ run TransactionTestCase

enter transaction

run TestCase

rollback transaction

problem solved

Page 69: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.6

Page 70: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

1.6

patch

Page 71: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.6

TEST_RUNNERimprovements

Test discoveryFull paths vs pseudo pathsDoctests discovery

Page 72: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.6

TEST_RUNNERimprovements

Test discoveryFull paths vs pseudo pathsDoctests discovery

Page 73: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.6

TEST_RUNNERimprovements

Test discoveryFull paths vs pseudo pathsDoctests discovery

Page 74: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.7

Page 75: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.7

unittest2

Page 76: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.7

unittest2

unittest

Page 77: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.7

LiveServerTestCase

StaticLiveServerTestCase

Page 78: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.8

Page 79: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

1.8

trace

Page 80: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCasebefore

enter atomic load fixtures

… exit atomic

close connections

1.8

Page 81: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCasebefore

enter atomic load fixtures

… exit atomic

close connections

1.8

Page 82: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCasebefore

enter atomic load fixtures

… exit atomic

close connections} times # of tests

1.8

Page 83: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCaseafter

enter atomic load fixtures enter atomic

… exit atomic exit atomic

close connections1.8

Page 84: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCaseafter

enter atomic load fixtures enter atomic

… exit atomic exit atomic

close connections1.8

Page 85: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCaseafter

enter atomic load fixtures enter atomic

… exit atomic exit atomic

close connections

}

times # of tests

1.8

Page 86: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCaseafter

enter atomic load fixtures enter atomic

… exit atomic exit atomic

close connections

}

times # of tests{once1.8

Page 87: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

Page 88: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

--parallel

Page 89: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

Page 90: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

s

Page 91: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

Page 92: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

suit

e

Page 93: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

par

titi

ons

Page 94: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

par

titi

ons

Page 95: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

par

titi

ons

Page 96: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

par

titi

ons

Page 97: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

par

titi

ons

Page 98: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

par

titi

ons

Page 99: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.9

wor

ker

sd

atab

ases

par

titi

ons

Page 100: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

nose multiprocess plugin

Page 101: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.10

Page 102: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.10

class SampleTestCase(TestCase): @tag('slow') def test_slow(self): ...

Page 103: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.10

./manage.py test --tag=slow

class SampleTestCase(TestCase): @tag('slow') def test_slow(self): ...

Page 104: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1.10

./manage.py test --tag=slow

./manage.py test --exclude-tag=slow

class SampleTestCase(TestCase): @tag('slow') def test_slow(self): ...

Page 105: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

nose attrib pluginpy.test markers

Page 106: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

nose attrib pluginpy.test markers

will do the same

Page 107: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TEST bedor what happens when you

run ./manage.py test

Page 108: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications
Page 109: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications
Page 110: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

$ ./manage.py test1

Page 111: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestRunner = get_runner(settings, options['testrunner']) test_runner = TestRunner(**options) failures = test_runner.run_tests(test_labels)

../management/commands/test.py2

Page 112: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestRunner = get_runner(settings, options['testrunner']) test_runner = TestRunner(**options) failures = test_runner.run_tests(test_labels)

../management/commands/test.py2

Page 113: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

3 self.setup_test_environment()

Page 114: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

3 self.setup_test_environment()

locmem email backend

Page 115: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

3 self.setup_test_environment()

locmem email backend

instrumented test renderer

Page 116: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

3 self.setup_test_environment()

locmem email backend

instrumented test renderer

deactivate translations

Page 117: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

4 self.build_suite(test_labels, extra_tests)

Page 118: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

4 self.build_suite(test_labels, extra_tests)

Page 119: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

5 self.setup_databases()

6 self.run_suite(suite)

7 self.teardown_databases(old_config)

Page 120: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

5 self.setup_databases()

6 self.run_suite(suite)

7 self.teardown_databases(old_config)

Page 121: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

5 self.setup_databases()

6 self.run_suite(suite)

7 self.teardown_databases(old_config)

Page 122: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

8 self.teardown_test_environment()

Page 123: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

original email backend

8 self.teardown_test_environment()

Page 124: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

original email backend

8

original test renderer

self.teardown_test_environment()

Page 125: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

original email backend

8

original test renderer

delete state and mailbox

self.teardown_test_environment()

Page 126: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

9 self.suite_result(suite, result)

len(result.failures) + len(result.errors)

if failures: sys.exit(1)

Page 127: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

all the test classes

Page 128: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

SimpleTestCase

TransactionTestCase

TestCase LiveServerTestCase

StaticLiveServerTestCase

Page 129: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

SimpleTestCase

no database queriesaccess to test clientfast

Page 130: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TransactionTestCase

allows database queriesaccess to test clientfastallows database transactionsflushes database after each test

Page 131: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

TestCase

allows database queriesaccess to test clientfasterrestricts database transactionsruns each test in a transaction

Page 132: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

LiveServerTestCase

acts like TransactionTestCaselaunches a live HTTP server in a separate thread

Page 133: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

StaticLiveServerTestCase

acts like TransactionTestCaselaunches a live HTTP server in a separate threadserves static files

Page 134: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

Page 135: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

Page 136: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

constructs requestsencodes data

Page 137: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

constructs requestsencodes data

Page 138: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

constructs requestsencodes data

Page 139: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

constructs requestsencodes data

Page 140: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

constructs requestsencodes data

Page 141: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

constructs requestsencodes data

Page 142: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

constructs requestsencodes data

Page 143: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

loads middleware

emulatesdisables CSRFconstructs requests

encodes data

Page 144: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

loads middleware

emulatesdisables CSRFconstructs requests

encodes data

Page 145: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

loads middleware

emulatesdisables CSRFconstructs requests

encodes data

Page 146: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

loads middleware

emulatesdisables CSRFconstructs requests

encodes data

Page 147: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Client

RequestFactory ClientHandler

statefulresponse++

handles redirects

loads middleware

emulatesdisables CSRFconstructs requests

encodes data

Page 148: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Quality

Page 149: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Factory Boy fixtures replacement with random and realistic values

Page 150: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Factory Boy fixtures replacement with random and realistic values

generated by

Faker

Page 151: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

property based testing with

Hypothesis

Page 152: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis import given

from hypothesis.strategies import text

@given(text())

def test_decode_inverts_encode(s):

assert decode(encode(s)) == s

Page 153: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis import given

from hypothesis.strategies import text

@given(text())

def test_decode_inverts_encode(s):

assert decode(encode(s)) == s

Page 154: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis import given

from hypothesis.strategies import text

@given(text())

def test_decode_inverts_encode(s):

assert decode(encode(s)) == s

Page 155: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis import given

from hypothesis.strategies import text

@given(text())

def test_decode_inverts_encode(s):

assert decode(encode(s)) == s

Page 156: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis import given

from hypothesis.strategies import text

@given(text())

def test_decode_inverts_encode(s):

assert decode(encode(s)) == s

Page 157: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis import given

from hypothesis.strategies import text

@given(text())

def test_decode_inverts_encode(s):

assert decode(encode(s)) == s

rerun for different values

Page 158: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis.extra.django.models import models

from hypothesis.strategies import integers

models(Customer).example()

models(Customer,

age=integers(

min_value=0,

max_value=120)

).example()

Page 159: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis.extra.django.models import models

from hypothesis.strategies import integers

models(Customer).example()

models(Customer,

age=integers(

min_value=0,

max_value=120)

).example()

Page 160: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis.extra.django import TestCase

from hypothesis import given

from hypothesis.extra.django.models import models

from hypothesis.strategies import lists, integers

class TestProjectManagement(TestCase):

@given(

models(Project, collaborator_limit=integers(min_value=0, max_value=20)),

lists(models(User), max_size=20))

def test_can_add_users_up_to_collaborator_limit(self, project, collaborators):

for c in collaborators:

if project.at_collaboration_limit():

with self.assertRaises(LimitReached):

project.add_user(c)

self.assertFalse(project.team_contains(c))

else:

project.add_user(c)

self.assertTrue(project.team_contains(c))

Page 161: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

from hypothesis.extra.django import TestCase

from hypothesis import given

from hypothesis.extra.django.models import models

from hypothesis.strategies import lists, integers

class TestProjectManagement(TestCase):

@given(

models(Project, collaborator_limit=integers(min_value=0, max_value=20)),

lists(models(User), max_size=20))

def test_can_add_users_up_to_collaborator_limit(self, project, collaborators):

for c in collaborators:

if project.at_collaboration_limit():

with self.assertRaises(LimitReached):

project.add_user(c)

self.assertFalse(project.team_contains(c))

else:

project.add_user(c)

self.assertTrue(project.team_contains(c))

Page 162: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class TestProjectManagement(TestCase):

@given(

models(Project, collaborator_limit=integers(min_value=0, max_value=20)),

lists(models(User), max_size=20))

def test_can_add_users_up_to_collaborator_limit(self, project, collaborators):

for c in collaborators:

if project.at_collaboration_limit():

with self.assertRaises(LimitReached):

project.add_user(c)

self.assertFalse(project.team_contains(c))

else:

project.add_user(c)

self.assertTrue(project.team_contains(c))

Page 163: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class TestProjectManagement(TestCase):

@given(

models(Project, collaborator_limit=integers(min_value=0, max_value=20)),

lists(models(User), max_size=20))

def test_can_add_users_up_to_collaborator_limit(self, project, collaborators):

for c in collaborators:

if project.at_collaboration_limit():

with self.assertRaises(LimitReached):

project.add_user(c)

self.assertFalse(project.team_contains(c))

else:

project.add_user(c)

self.assertTrue(project.team_contains(c))

Page 164: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class TestProjectManagement(TestCase):

@given(

models(Project, collaborator_limit=integers(min_value=0, max_value=20)),

lists(models(User), max_size=20))

def test_can_add_users_up_to_collaborator_limit(self, project, collaborators):

for c in collaborators:

if project.at_collaboration_limit():

with self.assertRaises(LimitReached):

project.add_user(c)

self.assertFalse(project.team_contains(c))

else:

project.add_user(c)

self.assertTrue(project.team_contains(c))

Page 165: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class TestProjectManagement(TestCase):

@given(

models(Project, collaborator_limit=integers(min_value=0, max_value=20)),

lists(models(User), max_size=20))

def test_can_add_users_up_to_collaborator_limit(self, project, collaborators):

for c in collaborators:

if project.at_collaboration_limit():

with self.assertRaises(LimitReached):

project.add_user(c)

self.assertFalse(project.team_contains(c))

else:

project.add_user(c)

self.assertTrue(project.team_contains(c))

Page 166: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Falsifying example: test_can_add_users_up_to_collaborator_limit(

self=TestProjectManagement(),

project=Project('', 1),

collaborators=[

User([email protected]),

User([email protected])

]

)

Traceback (most recent call last):

...

raise LimitReached()

manager.models.LimitReached

Page 167: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Property based testing is more complicated,

yet more valuable

Page 168: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Django test code coverage is

76%

Page 169: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Deceptive metric

Page 170: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

High coverage !=

high quality

Page 171: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Mutation testingavailable Python implementation: mutpy

Page 172: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

mut.py --target node --unit-test test_node

target unit test

Page 173: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

if foo and bar: do_this()

target unit test

Page 174: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

if foo and bar: do_this()

if foo or bar: do_this()

mutant unit test

Page 175: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

mutant

killed

Page 176: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

mutant

killed

mutant

survived

Page 177: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

AOR - arithmetic operator replacementBCR - break continue replacementCOI - conditional operator insertionCRP - constant replacementDDL - decorator deletionLOR - logical operator replacement

Page 178: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

[*] Start mutation process: - targets: django.utils.encoding - tests: tests.utils_tests.test_encoding [*] 10 tests passed: - tests.utils_tests.test_encoding [0.00533 s] [*] Start mutants generation and execution: ... [*] Mutation score [12.19066 s]: 32.1% - all: 88 - killed: 24 (27.3%) - survived: 55 (62.5%) - incompetent: 7 (8.0%) - timeout: 2 (2.3%)

Page 179: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

[*] Start mutation process: - targets: django.utils.encoding - tests: tests.utils_tests.test_encoding [*] 10 tests passed: - tests.utils_tests.test_encoding [0.00533 s] [*] Start mutants generation and execution: ... [*] Mutation score [12.19066 s]: 32.1% - all: 88 - killed: 24 (27.3%) - survived: 55 (62.5%) - incompetent: 7 (8.0%) - timeout: 2 (2.3%)

Page 180: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Django duration utils mutation score is

89%

Page 181: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Django duration utils mutation score is

89%and the coverage is 91%

Page 182: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Django encoding utils mutation score is

32%

Page 183: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Django encoding utils mutation score is

32%while the coverage is 63%

Page 184: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

django Testing tutorial

Page 185: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

my_app ├── __init__.py ├── admin.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py

Page 186: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

my_app ├── __init__.py ├── admin.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py

Page 187: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

When testing, more is better

Page 188: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

time

# of

tests

Page 189: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

# of tests

total

execu

tion t

ime

Page 190: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

slow tests, slow feedback loop

Page 191: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

8 tips on how to speed up your tests

Page 192: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

8 tips on how to speed up your tests

#5 will shock you

Page 193: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications
Page 194: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

Page 195: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

Page 196: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

Page 197: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

Page 198: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

5. use mocks EVERYWHERE

Page 199: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

5. use mocks EVERYWHERE

Page 200: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

5. use mocks EVERYWHERE

6. be vigilant of what gets created in setUp()

Page 201: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

5. use mocks EVERYWHERE

6. be vigilant of what gets created in setUp()

7. don’t save model objects if not necessary

Page 202: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

5. use mocks EVERYWHERE

6. be vigilant of what gets created in setUp()

7. don’t save model objects if not necessary

8. isolate unit tests

Page 203: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

5. use mocks EVERYWHERE

6. be vigilant of what gets created in setUp()

7. don’t save model objects if not necessary

8. isolate unit tests

Page 204: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

5. use mocks EVERYWHERE

6. be vigilant of what gets created in setUp()

7. don’t save model objects if not necessary

8. isolate unit tests

Page 205: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

1. use MD5PasswordHasher

2. consider in-memory sqlite3

3. have more SimpleTestCase

4. use setUpTestData()

5. use mocks EVERYWHERE

6. be vigilant of what gets created in setUp()

7. don’t save model objects if not necessary

8. isolate unit tests

Page 206: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class SimpleTest(TestCase): def setUp(self): for _ in range(10): Robot.objects.create()

6. be vigilant of what gets created in setUp()

Page 207: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class SimpleTest(TestCase): def setUp(self): for _ in range(10): Robot.objects.create()

6. be vigilant of what gets created in setUp()

Page 208: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

7. don’t save model objects if not necessary

Page 209: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

7. don’t save model objects if not necessary

Robot.objects.create()instead of

Page 210: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

7. don’t save model objects if not necessary

Robot.objects.create()

Robot()

instead of

maybe do

Page 211: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

7. don’t save model objects if not necessary

Robot.objects.create()

Robot()

RobotFactory.build()

instead of

maybe do

or

Page 212: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

7. don’t save model objects if not necessary

Robot.objects.create()

Robot()

RobotFactory.build()

RobotFactory.stub()

instead of

maybe do

or

or

Page 213: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

7. don’t save model objects if not necessary

Robot.objects.create()

Robot()

RobotFactory.build()

RobotFactory.stub()

factory boy

instead of

maybe do

or

or }

Page 214: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

8. isolate unit tests

Page 215: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

8. isolate unit tests

Page 216: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

8. isolate unit tests

Page 217: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

8. isolate unit tests

unit tests functional tests

Page 218: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

8. isolate unit tests

unit tests functional tests

./manage.py test --tag=unit

Page 219: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications
Page 220: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Ugh, taxes!

Page 221: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Product ProductQuestionnaire

name ingredients price

product category drink_category food_category has_decorations is_coated_in_chocolate is_warm is_cold

Page 222: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications
Page 223: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Production code

Test

Page 224: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class ProductQuestionnaireCreate(CreateView):

def form_valid(self, form):

if is_biscuit and is_coated_in_chocolate:

set_vat_20()

return super().form_valid(form)

class ProductQuestionnaireCreateTestCase(TestCase):

def test_20p_vat_if_coated_in_chocolate_biscuit(self):

product = ProductFactory()

response = self.client.post(self.url, {'q1': 'a1', 'q2': 'a2'})

product.refresh_from_db()

self.assertEqual(product.vat, 20)

take 1

Page 225: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class ProductQuestionnaireCreate(CreateView):

def form_valid(self, form):

if is_biscuit and is_coated_in_chocolate:

set_vat_20()

return super().form_valid(form)

class ProductQuestionnaireCreateTestCase(TestCase):

def test_20p_vat_if_coated_in_chocolate_biscuit(self):

product = ProductFactory()

response = self.client.post(self.url, {'q1': 'a1', 'q2': 'a2'})

product.refresh_from_db()

self.assertEqual(product.vat, 20)

take 1

Page 226: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class ProductQuestionnaireCreate(CreateView):

def form_valid(self, form):

return super().form_valid(form)

Page 227: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class ProductQuestionnaireCreateTestCase(TestCase):

def test_20p_vat_if_coated_in_chocolate_biscuit(self):

def test_0p_vat_if_baguette(self):

def test_0p_vat_if_flapjack(self):

def test_20p_vat_if_cereal_bar(self):

Page 228: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

To test if I need to pay 20% VAT for biscuits coated in chocolate, I need to:

go through the router

interact with database

send input to receive output

Page 229: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Mocks are not a solution

Page 230: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class ProductQuestionnaireForm(forms.ModelForm):

def save(self, commit=True):

instance = super().save(commit)

if is_biscuit and is_coated_in_chocolate:

set_vat_20()

return instance

take 2

class ProductQuestionnaireFormTestCase(TestCase):

def test_20p_vat_if_coated_in_chocolate_biscuit(self):

product = ProductFactory()

form = ProductQuestionnaireForm(data={'k1': 'v1', 'k2': 'v2'})

self.assertTrue(form.is_valid())

form.save()

product.refresh_from_db()

self.assertEqual(product.vat, 20)

Page 231: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

class ProductQuestionnaireForm(forms.ModelForm):

def save(self, commit=True):

instance = super().save(commit)

if is_biscuit and is_coated_in_chocolate:

set_vat_20()

return instance

take 2

class ProductQuestionnaireFormTestCase(TestCase):

def test_20p_vat_if_coated_in_chocolate_biscuit(self):

product = ProductFactory()

form = ProductQuestionnaireForm(data={'k1': 'v1', 'k2': 'v2'})

self.assertTrue(form.is_valid())

form.save()

product.refresh_from_db()

self.assertEqual(product.vat, 20)

Page 232: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

To test if I need to pay 20% VAT for biscuits coated in chocolate, I need to:

go through the router

interact with database

send input to receive output

Page 233: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

take 3

class VATCalculator(object):

def calculate_vat(self, **kwargs):

if is_biscuit and is_coated_in_chocolate:

return 20

class VATCalculatorTestCase(SimpleTestCase):

def test_20p_vat_if_coated_in_chocolate_biscuit(self):

calc = VATCalculator()

self.assertEqual(calc.calculate_vat(

is_biscuit=True, is_coated_in_choco=True

))

Page 234: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

reusability

testability

extensibility

Page 235: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

To test if I need to pay 20% VAT for biscuits coated in chocolate, I need to:

go through the router

interact with database

send input to receive output

Page 236: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications
Page 237: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Tests have more in them than we think

Page 238: TESTING in DJANGO - Simple is Better Than Complex · #2333 As an added incentive, this is a feature that is present in Rails. Add unit test framework for end-user Django applications

Happy testing

and big bear hug thanks!