Opened 16 years ago

Closed 16 years ago

Last modified 13 years ago

#10183 closed (fixed)

assertContains fails when there is unicode in the response content

Reported by: drakonen Owned by: nobody
Component: Testing framework Version: 1.0
Severity: Keywords: testcases, assertContains, assertNotContains
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

# views.py
#

from django.shortcuts import render_to_response

def index(request):
    return render_to_response('index.html')

#
# index.html

aaäaa

#
# tests.py

from django.test import TestCase

class TestViews(TestCase):
    def test_index(self):
        response = self.client.get('/')
        self.assertContains(response, u'aa')


#
# results in:

======================================================================
ERROR: test_index (stuff.tests.TestViews)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/johan/devel/tester/stuff/tests.py", line 6, in test_index
    self.assertContains(response, u'aa')
  File "/usr/lib/python2.5/site-packages/django/test/testcases.py", line 267, in assertContains
    real_count = response.content.count(text)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128)

----------------------------------------------------------------------

Attachments (5)

assertContainsPatch.diff (1.5 KB ) - added by drakonen 16 years ago.
django.test.testcases_assertContainsPatch.2.diff (1.6 KB ) - added by trbs 16 years ago.
10183-cant-reproduce.diff (3.4 KB ) - added by Eric Holscher 16 years ago.
Patch of the test case I made that couldn't reproduce the above.
10183-assertcontains-unicode-testcase.diff (2.8 KB ) - added by trbs 16 years ago.
10183-django.test.testcases_assertContainsPatch.3.diff (1.5 KB ) - added by trbs 16 years ago.

Download all attachments as: .zip

Change History (14)

by drakonen, 16 years ago

Attachment: assertContainsPatch.diff added

comment:1 by trbs, 16 years ago

Keywords: testcases assertContains assertNotContains added

A little rational behind the patch;

Python raised the UnicodeDecodeError because it's asked to count a unicode string within a non-unicode string.
HttpResponse's content property uses smart_str to create content data, it would seem to make sense to do
the same for any text used in assertContains and assertNotContains.

I've added an updated patch to this ticket which uses smart_str(text, response._charset) which matches the HttpResponse
object behavior. Could also have used settings.DEFAULT_CHARSET but it seems with ticket #10190 this might change later on so response._charset seems a safer bet :)

comment:2 by (none), 16 years ago

milestone: post-1.0

Milestone post-1.0 deleted

comment:3 by Eric Holscher, 16 years ago

Triage Stage: UnreviewedAccepted

This makes sense. Having the tests mimick what normal Django does is probably a good idea.

comment:4 by Claude Paroz, 16 years ago

Been confronted to this today. What prevents this to be included in 1.1 ?

comment:5 by Jacob, 16 years ago

milestone: 1.1

by Eric Holscher, 16 years ago

Attachment: 10183-cant-reproduce.diff added

Patch of the test case I made that couldn't reproduce the above.

comment:6 by Eric Holscher, 16 years ago

Resolution: invalid
Status: newclosed

I couldn't reproduce this. I have attached a test case to Django that passes. If you can make one that fails, please attach it to the case and reopen the ticket.

comment:7 by trbs, 16 years ago

Resolution: invalid
Status: closedreopened

The reason the test case did not fail was because the assertion is not unicode.

I've attached a test case that does fail, it uses some Japanese in the template and tries to match a Unicode string in assertContains. Also attached a slight improvement on the patch for testcases.py because before a failed assertion did not use the smart_str version of the text resulting in "AssertionError: <unprintable AssertionError object>"

With the new test case it fails as follows:

======================================================================
ERROR: test_unicode_contains (regressiontests.test_client_regress.models.AssertContainsTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/trbs/django/trunk/tests/regressiontests/test_client_regress/models.py", line 71, in test_unicode_contains
    self.assertContains(r, '\xe5\xb3\xa0'.decode('utf-8'))
  File "/home/trbs/django/trunk/django/test/testcases.py", line 333, in assertContains
    real_count = response.content.count(text)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 2: ordinal not in range(128)

----------------------------------------------------------------------
Ran 48 tests in 4.005s

FAILED (errors=1)
Destroying test database...

Hope this clears things up, otherwise you can also drop me a line on irc :)

comment:8 by Russell Keith-Magee, 16 years ago

Resolution: fixed
Status: reopenedclosed

(In [10415]) [1.0.X] Fixed #10183 -- Corrected the handling of unicode in assertContains and assertNotContains. Thanks to trbs for the patch.

Merge of r10414 from trunk.

comment:9 by Jacob, 13 years ago

milestone: 1.1

Milestone 1.1 deleted

Note: See TracTickets for help on using tickets.
Back to Top