Opened 8 years ago

Closed 8 years ago

Last modified 5 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: UI/UX:

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 8 years ago.
django.test.testcases_assertContainsPatch.2.diff (1.6 KB) - added by trbs 8 years ago.
10183-cant-reproduce.diff (3.4 KB) - added by Eric Holscher 8 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 8 years ago.
10183-django.test.testcases_assertContainsPatch.3.diff (1.5 KB) - added by trbs 8 years ago.

Download all attachments as: .zip

Change History (14)

Changed 8 years ago by drakonen

Attachment: assertContainsPatch.diff added

comment:1 Changed 8 years ago by trbs

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 Changed 8 years ago by (none)

milestone: post-1.0

Milestone post-1.0 deleted

comment:3 Changed 8 years ago by Eric Holscher

Triage Stage: UnreviewedAccepted

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

comment:4 Changed 8 years ago by Claude Paroz

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

comment:5 Changed 8 years ago by Jacob

milestone: 1.1

Changed 8 years ago by Eric Holscher

Attachment: 10183-cant-reproduce.diff added

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

comment:6 Changed 8 years ago by Eric Holscher

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 Changed 8 years ago by trbs

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 Changed 8 years ago by Russell Keith-Magee

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 Changed 5 years ago by Jacob

milestone: 1.1

Milestone 1.1 deleted

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