Errata

Test-Driven Development with Python

Errata for Test-Driven Development with Python

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
ePub
Ch. 3, Unit Testing w/a view, test.py listing

In the epub 1st edition, the three assertions are improperly indented.

In my edition, the first self.assertTrue(..." is at the left margin, when it should be part of the test definiton (two tabs in).
2nd assertion, "self.assertIn(...." is correct
3rd assertion is back at the left margin.

It look some head-scratching to realize that they all had to be part of the test definition, and that the 2nd was correctly positioned, not the 1st and 3rd.

Note from the Author or Editor:
wontfix.

Ari Davidow  Aug 29, 2016 
Printed, PDF, ePub
Page 10000
ch01.html

command line operation:

# mv functional_tests.py superlists/

is not consistent with the resulting git status in the following paragraphs.

It is also not consistent with the source code bundle.
After cloning it, do a `git checkout chapter_01`
to see for yourself.
It is also not inside the superlists directory when git is pointing at branches chapter_02 nor chapter_03.

Note from the Author or Editor:
2e is out, so wontfix.

Anonymous  Jul 04, 2016 
Printed
Page 61
list/tests.py code

While retrieving saved items with Items.objects.all() it is assumed that objects are returned in order they're insterted in database. This is not true, without order_by() order returned is "in no particular order", thus that test may fail randomly. It's not even guaranteed that primary keys are in in order of insertion so there should be some column, like insertion time stamp for ordering purposes.

Note from the Author or Editor:
reader is correct, strictly speaking, although it's never been a problem. we're relying on an undocumented / unsupported feature, so that's not ideal. will have a think about how to address this

Jani Tiainen  Jan 12, 2016 
Printed
Page xxviii
2nd paragraph

"Chichago School" should likely be "Chicago School"
(particularly amusing when thanking Charles for style & grammar assistance)

Note from the Author or Editor:
this is fixed in the latest edition.

Tim Chase  Oct 13, 2015  Oct 16, 2015
PDF
Page 204
Code listing under 'Using the Form in the View'

Inconsistent use of single/double quotes.

The key 'form' is double quoted in the last line of the code snippet:
return render(request, 'home.html', {"form": form})

Note from the Author or Editor:
this is the kind of thing that's definitely going to bug people with mild OCD, but it's too much trouble to fix at this stage....

Anonymous  Aug 28, 2015  Oct 16, 2015
PDF
Page 424
code listing for 'deploy_tools/provision.ansible.yaml'

In the newest version of Ansible (1.9.2. just tested) the $inventory_hostname does not work any more.

In the code listing for 'deploy_tools/provision.ansible.yaml':
vars:
host: $inventory_hostname

should be replaced with

vars:
host: "{{ inventory_hostname }}

or the variable 'host' could be replace with 'inventory_hostname' at all places.

Note from the Author or Editor:
have fixed in latest draft.

Anonymous  Aug 26, 2015  Oct 16, 2015
PDF
Page 426
First paragraph

The ansible command uses a different file name for the inventory:
ansible-playbook -i ansible.inventory provision.ansible.yaml --limit=staging
But the file is named inventory.ansible so the command should be
ansible-playbook -i inventory.ansible provision.ansible.yaml --limit=staging

Note from the Author or Editor:
already fixed in latest draft.

Anonymous  Aug 26, 2015  Oct 16, 2015
Mobi, Other Digital Version
Page 117
A Final Refactor Using URL includes - lists/urls.py (ch06l045).

lists/urls.py (ch06l045). is missing "from lists import views" in addtion to the django.conf import. Also as noted in author's github https://github.com/hjwp/book-example/blob/chapter_06/lists/urls.py

from django.conf.urls import url

from lists import views

Note from the Author or Editor:
fixed in latest version

Anonymous  Jun 30, 2015  Oct 16, 2015
Printed
Page 439
top of page

Chef, Puppett, Salt....

should read

Chef, Puppet, Salt

Note from the Author or Editor:
will fix on atlas.

Jürgen  Dec 19, 2014  Mar 06, 2015
Printed, PDF
Page 347
Bulgaria

Below *Moving Down to the Forms Layer* header, in NewListForm's code. The save method
lacks an equal sign to list_. owner.


It's shown as:
if owner:
list_.owner owner


Should be:
if owner:
list_.owner = owner

Note from the Author or Editor:
this is fixed in the latest release, anton must be reading an old version.

Anton Antonov  Dec 11, 2014  Sep 19, 2014
Printed
Page 147
After "Creating the Database.." Let's try the FTs again...

Test fails as selenium is not installed.

Note from the Author or Editor:
ah yes, this can happen if we don't install selenium into the virtualenv. will see if i can clarify...

Jurgen  Dec 10, 2014  Mar 06, 2015
Printed
Page 84
Figure 6-1

In Figure 6-1, the "Does the application need Refactoring" element lacks a "Yes" on the connection down to the Unit test cycle

Note from the Author or Editor:
yup. not sure i'm ever going to get round to fixing this though, it's a bit too much hassle...

Jurgen  Dec 04, 2014  Mar 06, 2015
Printed, PDF
Page 359
Para 1

"conceivable" s/b "conceivably" (oh shame on my pedantic mood!)

Note from the Author or Editor:
will fix.

Iain Houston  Nov 26, 2014  Mar 06, 2015
Printed, PDF
Page 354
Aside

"We'd forgotten about to ..." s/b "We'd forgotten to ..."

Note from the Author or Editor:
will fix.

Iain Houston  Nov 26, 2014  Mar 06, 2015
Printed, PDF
Page 260
Tip/suggestion paragraph

In page 258, code snippet below "A Simple Mock to Unit Tests Our Initialize Function" the reader is instructed to add <a id="id_login">Sign in</a>, but in
the tip/suggestion paragraph on 260 the reader is reminded to add <div id="id_login">. It should be also an <a> tag.

Note from the Author or Editor:
confirmed. will fix in atlas.

Anton Antonov  Nov 22, 2014  Mar 06, 2015
Printed, PDF
Page 308
accounts/authentication.py

Code snippet requires "import logging"

Note from the Author or Editor:
Iain is correct, will fix it on atlas

Iain Houston  Nov 21, 2014  Mar 06, 2015
Printed, PDF
Page Appendix B
ch31l002

ch31l002 should also be prepended with "from lists.views import HomePageView"

Note from the Author or Editor:
Will fix.

Iain Houston  Nov 11, 2014  Mar 06, 2015
PDF
Page 237
"Staging Deploy" section, "Restart Gunicorn"

Should the following:
"... sudo restart gunicorn-superlists.ottg.eu"

actually be this?
"... sudo restart gunicorn-superlists-staging.ottg.eu"

Note that we're in the section where we're talking about the staging server, not where we're covering the live/production server.

(Or perhaps I did something incorrectly myself when I followed along in chapter 8, and I'm only seeing the effect here.)

Note from the Author or Editor:
absolutely right, will fix...

Andrew Enfield  Sep 12, 2014  Sep 19, 2014
chapter 7
United States

the class StaticLiveServerCase was renamed to StaticLiveServerTestCase in django 1.7 release.

https://code.djangoproject.com/ticket/23374

Note from the Author or Editor:
have fixed this in the latest version on atlas.

James Boorn  Sep 03, 2014  Sep 19, 2014
Printed
Page 48
Figure 4-4

The "Does the application need Refactoring?" element in the flow chart in Figure 4-4 has the 'Yes' label missing (in the connection arrow that leads to the big box below)

Note from the Author or Editor:
Sure enough, it's missing from the image... Will try and get a new image together and then push it up to atlas...

Mark  Aug 21, 2014  Sep 19, 2014
Printed
Page 31
(4) point in the list in the first paragraph

The code (on page 30) referenced by the text at page 31 is this:

self.assertIn(b'<title>To-Do lists</title>', response.content)

and the text at page 30 says:

And we want a <title> tag somewhere in the middle, with the word "To-Do" in it

but the assert checks that the <title> tag contains exactly "To-Do lists".

Note from the Author or Editor:
I'll fix this in atlas

Mark  Aug 21, 2014  Sep 19, 2014
Other Digital Version
online
Chapter 10, Section "Refactor: Transferring the new_item Functionality into view_list"

It is written:

"Let?s take all the old tests from NewItemTest, the ones that are about saving POST requests to existing lists, and move them into ListViewTest. As we do so, we also make them point at the base list URL, instead of ?/new_item:"

I believe it's mistake and the author means "/add_item" which is the word being used both urls.py and test_views.py. Example, in urls.py:

url(r'^(\d+)/add_item$', 'lists.views.add_item', name='add_item'),

Note from the Author or Editor:
am fixing this.

Ze Santos  Jun 26, 2014  Jul 23, 2014
ePub
Page 1162
index

Spelling error in index "Fuctional Core" in the "F" section in the index.

Note from the Author or Editor:
quite right, i'll fix it...

John Antolak  Jun 20, 2014  Jul 23, 2014
PDF
Page 9
Bottom, after last 'git status' command

git status results should indicate that .gitignore has been modified:

On branch master

Initial commit

Changes to be committed:
(use "git rm --cached <file>..." to unstage)

new file: .gitignore
new file: functional_test.py
new file: manage.py
new file: superlists/__init__.py
new file: superlists/settings.py
new file: superlists/urls.py
new file: superlists/wsgi.py

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: .gitignore

Note from the Author or Editor:
Well spotted! And very frustrating, my tests should have picked this up. turns out they weren't testing what I though they were, classic mistake.

I will fix it for the next edition.

Shafique Jamal  Jun 11, 2014  Jul 23, 2014
PDF
Page 15
Next to symbols 2 and 3

The sentence currently reads, "setUp and tearDown special methods..." It should be updated to, "setUp and tearDown are special methods..."

Note from the Author or Editor:
fixed in latest draft

Ramces Chirino  May 27, 2014  Jul 23, 2014
PDF
Page 74
1st paragraph

The paragraph states:

".. as well as a new file, db.sqlite3. Let?s add the first three, and then add the database to our .gitignore:"

But db.sqlite3 is already added to .gitignore (on page 8).

Note from the Author or Editor:
fixed in my latest draft

Fredrik Larsson  May 18, 2014  Jun 09, 2014
Other Digital Version

[Site]
http://chimera.labs.oreilly.com/books/1234000000754/pr01.html#_conventions_used_in_this_book
[Error]
> Constant width italic
> Shows text that should be replaced with user-supplied values or by values determined by > context.
The CSS font style of the first line of the quotes above isn't italic, it displays using a regular font style. This seems caused by (from the page source):
> <em><code class="literal">Constant width italic</code></em>
and from the CSS of $('code.literal'):
> font-style: normal;
seems to be the cause.

Note from the Author or Editor:
this is presumably a deficiency in the chimera formatting?

tbh i don't use constant width italic at all in the book, so we could just drop the whole quote

Stephen W  May 17, 2014  Jun 09, 2014
PDF
Page 414
2nd paragraph

"We can see they?re both happening in the generiv view's..." Change "generiv" to "generic".

Note from the Author or Editor:
fixed in latest draft

Anonymous  May 05, 2014  Jul 23, 2014
PDF
Page 298
listing at the end of page

the listing should be for file lists/tests/test_views.py instead of lists/tests.py

Jan Dittberner  Apr 20, 2014  Jun 09, 2014
PDF
Page 296
last paragraph and subsequent listings (including those on next page)

just adding {% block %} tags around a template block does not make it necessary to use {% block ... %}{{ block.super }}{% endblock %} in derived templates, instead it is necessary to define an empty block in derived templates that do not need the block.

Note from the Author or Editor:
fixed in latest draft

Jan Dittberner  Apr 20, 2014  Jun 09, 2014
PDF
Page 295
first two listings

The first listing should be in lists/templates/base.html instead of lists/templates/home.html. The test should go into lists/tests/test_views.py instead of lists/test_views.py that does not exist if you follow the guideline in previous chapters.

Note from the Author or Editor:
fixed in latest draft

Jan Dittberner  Apr 20, 2014  Jun 09, 2014
PDF
Page 294
listing

The showed template snipped should be in lists/templates/base.html instead of lists/templates/home.html.

Note from the Author or Editor:
fixed in latest draft

Jan Dittberner  Apr 20, 2014  Jun 09, 2014
Other Digital Version
nil
Chapter 6

Section: Implementing the new design using TDD

Last comment in the code box following "Delete everything from the comments just before the self.fail..."

The first word contains a typo:
# Satisified, they both go back to sleep

Note from the Author or Editor:
fixed in latest draft

Anonymous  Apr 11, 2014  Jul 23, 2014
Other Digital Version
nil
Chapter 5 / Section Saving the POST to the database / Beginning of a paragraph

Missing word (possibly "ignore") in the following sentence:

Remember, I?m not saying you should always glaring problems like this in "real life".

Note from the Author or Editor:
fixed in latest draft.

Anonymous  Apr 10, 2014  Jul 23, 2014
PDF
Page 62
The figure

The figure is not of the error, but of the working application.

Note from the Author or Editor:
Hi there, thanks for submitting this erratum. I've fixed it in the latest release of the book. Please don't hesitate to send any other comments, feedback or suggestions! obeythetestinggoat@gmail.com

Ramon Maria Gallart  Jan 30, 2014  Jun 09, 2014
ePub
Page 266
listing on bottom of page

The following code does not work with Django 1.6:

def validate_unique(self):
try:
self.instance.validate_unique()
except ValidationError:
self._update_errors({'text': [DUPLICATE_ITEM_ERROR]})

The _update_errors() method expects an error with an 'error_dict' attribute and not the dict itself. The base method in django.forms.BaseModelForm passes the ValidationError instance itself to _update_errors(). Therefore the following fix is working:

def validate_unique(self):
try:
self.instance.validate_unique()
except ValidationError as e:
e.error_dict = {'text': [DUPLICATE_ITEM_ERROR]}
self._update_errors(e)

Note from the Author or Editor:
to be fixed as part of upgrade to 1.6

Anonymous  Nov 11, 2013  Jun 09, 2014
ePub
Page 113
Just prior to header "What we skipped over...."

I found moving the left margin by a fixed amount (-10px) didn't necessarily yield a pass. My window was slightly smaller, and thus I had to reduce it by -15px to pass.

This leads me to believe that the results of the test vary according to computer, which is not very robust. It seems to me that making the delta in "assertAlmostEqual" a fraction of the screen width as opposed to a fixed amount might be a more flexible solution (though this is only my opinion).

Note from the Author or Editor:
fixed in latest versions

Sean Robertson  Aug 29, 2013  Jun 09, 2014
PDF
Page 13
Top of page

The block of code:

if __name__ == '__main__':
unittest.main()

...appears on the following page from the proceeding class declaration and because they are separated the indentation level is lost and it is easy to include it in the class declaration (which causes the test to never run). I recommend you keep all the code on one page.

Note from the Author or Editor:
to be fixed when book goes to production?

Andrea Costantini  Jun 19, 2013  Jun 09, 2014
Mobi
Page 198
United States

functional_test.py reads:

browser - webdriver.Firefox()

s/b

browser = webdriver.Firefox()

john brasher  Apr 27, 2013  May 08, 2013
PDF
Page 13
3rd bullet point

The text describes the "if __name__ == '__main__' clause" in this bullet point. Nowhere can I find in the code given previously that this clause is used. Not including this clause somewhere in the code will cause it to not run properly and not give the result from your example in the book.

SoonerBourne  Apr 08, 2013  May 08, 2013
PDF
Page 33
last code block

assert wibble = 3
is a SyntaxError. It should be
assert wibble == 3

James O'Donnell  Apr 06, 2013  May 08, 2013
PDF
Page 33
In the middle of the page, first paragraph after heading The ?Don?t test constants? rule, and templates to the rescue

In bold, there is "Don?t test contants", and it should be constants...

Marek Turnovec  Apr 04, 2013  May 08, 2013
PDF
Page 16
bullet 2

"or at least to get past its current failure"
should be
"or at least to get passed its current failure"

James O'Donnell  Apr 03, 2013  May 08, 2013
PDF
Page 15
Tip copy

"dev. server" should be "dev server"

James O'Donnell  Apr 03, 2013  May 08, 2013
PDF
Page 12
last paragraph

Words in the Constant width font span multiple lines. Examples include:

last paragraph on line 12: test_can_start_a_list_and_retrieve_it_later

second paragraph on page 13: unittest and assertEqual

Note from the Author or Editor:
to be fixed in production?

James O'Donnell  Apr 03, 2013  Jun 09, 2014
PDF
Page 12
functional_tests.py code example

The code sample is missing the concluding:

if __name__ == '__main__':
unittest.main()

... which is mentioned in the 5th bullet point immediately afterwards. Without it, the test simply returns with no output to the command line.

Cheers,
Mike

Michael Allan  Apr 03, 2013  May 08, 2013
PDF
Page Cover
size

The cover is sized approximately 29" x 38" which makes it more difficult to use. When telling the reader to fit to width, it bases the magnification on this one oversize page's width, leaving the real pages far too small to read.

Note from the Author or Editor:
I believe this has been fixed.

David H. Brown  Apr 03, 2013  May 08, 2013
PDF
Page 5
United Kingdom

Just a suggestion.
You mention an 'app', and most of the command line stuff is from
some baseline directory?
I was concerned that I was issuing commands from the wrong directory
until I realised they were all from the same directory?
More difficult since there are two 'superlist' directories?
perhaps suggest a working directory,
then for your command line input 'show' the directory

app> ...... cmd

One other, PDF page 34
self.assertTrue(response.content.strip().endswith('</html>'))

Not needed on my Linux box (just fyi)
the preceding example works fine.

Good luck.

Dave Pawson  Apr 03, 2013  May 08, 2013
PDF
Page 33
2nd to last sentence

Sentence reads:

There are lots of Python templating frameworks out
there, and Django has its own which work very well.

'work' should be plural:

There are lots of Python templating frameworks out
there, and Django has its own, which works very well.

Jeff Orr  Mar 31, 2013  May 08, 2013
PDF
Page 24
5th paragraph

Should the following be in asterisks?:

*git diff* # should show changes to urls.py, tests.py, and views.py
*git commit -am"First unit test and url mapping, dummy view"*

Should it be:

$ git diff # should show changes to urls.py, tests.py, and views.py
$ git commit -am"First unit test and url mapping, dummy view"

Jeff Orr  Mar 31, 2013  May 08, 2013
PDF
Page 22
1st paragraph, second sentence

Sentence starting with:

Well, bewarned:

should be:

Well, be warned:

Jeff Orr  Mar 31, 2013  May 08, 2013
PDF
Page 21
1st paragraph

Sentence reads:

So we want to test two thing:

'thing' needs to be plural:

So we want to test two things:

Jeff Orr  Mar 31, 2013  May 08, 2013
PDF
Page 20
3rd paragraph

Should the following be listed as command prompts?

*git status*
# should show you superlists/settings.py has changed and lists/ is untracked
*git add superlists/settings.py*
*git add lists*
*git diff --staged* # will show you the diff that you're about to commit
*git commit -m"Add app for lists, with deliberately failing unit test"*
# I'll let you guess what commit -m does!


Instead:

$ git status
# should show you superlists/settings.py has changed and lists/ is untracked
$ git add superlists/settings.py
$ git add lists
$ git diff --staged # will show you the diff that you're about to commit
$ git commit -m"Add app for lists, with deliberately failing unit test"
# I'll let you guess what commit -m does!

Jeff Orr  Mar 31, 2013  May 08, 2013
PDF
Page 18
2nd paragraph, 3rd sentence

The sentence reads:

Well, a test failure means we?re allowed to change production code, so let?s open up the mysite/settings.py file.

I think the file settings.py should be in the folder superlists:

Well, a test failure means we?re allowed to change production code, so let?s open up the superlists/settings.py file.

Jeff Orr  Mar 31, 2013  May 08, 2013
PDF
Page 17
3rd paragraph, 1st sentence

Sentence reads:

Does that may seem slightly redundant?

I think it should read:

Does that seem slightly redundant?

Jeff Orr  Mar 31, 2013  May 08, 2013
PDF
Page 13
3rd paragraph

The third paragraph references code that is not in the code example on page 12.

if __name__ == '__main__' clause and unittest.main() are not found on page 12 in the code.

Jeff Orr  Mar 30, 2013  May 08, 2013
PDF
Page 13
2nd paragraph, 2nd sentence

Sentence starts:

uni
ttest provides lots helper functions like this to make test assertions,

Should have word 'of':

uni
ttest provides lots of helper functions like this to make test assertions,

Jeff Orr  Mar 30, 2013  May 08, 2013
PDF
Page 12
3rd paragraph, 2nd sentence

extra space in compound adjective after hyphen:

ready- made

should be:

ready-made

Jeff Orr  Mar 30, 2013  May 08, 2013
PDF
Page 11
2nd sentence

The following comment line reads:

# that the site has generate a unique URL for her -- there is some

It should be:

# that the site has generated a unique URL for her -- there is some

Jeff Orr  Mar 30, 2013  May 08, 2013
PDF
Page 4
In tip/suggestion/note

Spelling error and no punctuation at end of sentence:

If you see an ImportError, or it looks like selenium if failing to open Firefox, you should go back and take another look at the pre-requisites

Should be:

If you see an ImportError, or it looks like selenium is failing to open Firefox, you should go back and take another look at the pre-requisites.

Jeff Orr  Mar 29, 2013  May 08, 2013
PDF
Page 3
code block after 2nd paragraph

In the code block I see:

browser.get('http://localhost:8000')

On page 4, there is this sentence in the first paragraph:

You should see a browser window pop up, try and open up localhost:8001, and then the Python error message.

Either the code block should be modified to reference port 8001, or the sentence should be modified to reference port 8000. These are not consistent.

Jeff Orr  Mar 29, 2013  May 08, 2013
PDF
Page 1
2nd paragraph

Sentence as is:

Now, normally first step in web development is getting your web framework installed and configured.

I think it should include the word "the":

Now, normally the first step in web development is getting your web framework installed and configured.

Jeff Orr  Mar 29, 2013  May 08, 2013
PDF
Page x
1st paragraph under heading "Contacting O'Reilly"

Text found was:

If you?d like to get in touch with my beloved publisher with any questions about concerning this book, contact details follow:

I think it should be:

If you?d like to get in touch with my beloved publisher with any questions about this book, contact details follow:

Jeff Orr  Mar 29, 2013  May 08, 2013