Index: django/contrib/admin/templates/registration/password_change_form.html
===================================================================
--- django/contrib/admin/templates/registration/password_change_form.html	(revision 8471)
+++ django/contrib/admin/templates/registration/password_change_form.html	(working copy)
@@ -13,11 +13,11 @@
 
 <form action="" method="post">
 
-{% if form.old_password.errors %}{{ form.old_password.html_error_list }}{% endif %}
+{% if form.old_password.errors %}{{ form.old_password.errors }}{% endif %}
 <p class="aligned wide"><label for="id_old_password">{% trans 'Old password:' %}</label>{{ form.old_password }}</p>
-{% if form.new_password1.errors %}{{ form.new_password1.html_error_list }}{% endif %}
+{% if form.new_password1.errors %}{{ form.new_password1.errors }}{% endif %}
 <p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
-{% if form.new_password2.errors %}{{ form.new_password2.html_error_list }}{% endif %}
+{% if form.new_password2.errors %}{{ form.new_password2.errors }}{% endif %}
 <p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
 
 <p><input type="submit" value="{% trans 'Change my password' %}" /></p>
Index: django/contrib/auth/tests/views.py
===================================================================
--- django/contrib/auth/tests/views.py	(revision 8471)
+++ django/contrib/auth/tests/views.py	(working copy)
@@ -1,5 +1,8 @@
 
+import os
 import re
+
+from django.conf import settings
 from django.contrib.auth.models import User
 from django.test import TestCase
 from django.core import mail
@@ -86,3 +89,76 @@
         self.assertEquals(response.status_code, 200)
         self.assert_("The two password fields didn't match" in response.content)
 
+
+class ChangePasswordTest(TestCase):
+    fixtures = ['authtestdata.json']
+    urls = 'django.contrib.auth.urls'
+    
+    def setUp(self):
+        self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
+        settings.TEMPLATE_DIRS = (
+            os.path.join(
+                os.path.dirname(__file__), 
+                'templates'
+            )
+        ,)
+    
+    def tearDown(self):
+        settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
+    
+    def login(self, password='password'):
+        response = self.client.post('/login/', {
+            'username': 'testclient',
+            'password': password
+            }
+        )
+        self.assertEquals(response.status_code, 302)
+        self.assert_(response['Location'].endswith('/accounts/profile/'))
+    
+    def fail_login(self, password='password'):
+        response = self.client.post('/login/', {
+            'username': 'testclient',
+            'password': password
+            }
+        )
+        self.assertEquals(response.status_code, 200)
+        self.assert_("Please enter a correct username and password. Note that both fields are case-sensitive." in response.content)
+    
+    def logout(self):
+        response = self.client.get('/logout/')
+    
+    def test_password_change_fails_with_invalid_old_password(self):
+        self.login()
+        response = self.client.post('/password_change/', {
+            'old_password': 'donuts',
+            'new_password1': 'password1',
+            'new_password2': 'password1',
+            }
+        )
+        self.assertEquals(response.status_code, 200)
+        self.assert_("Your old password was entered incorrectly. Please enter it again." in response.content)
+    
+    def test_password_change_fails_with_mismatched_passwords(self):
+        self.login()
+        response = self.client.post('/password_change/', {
+            'old_password': 'password',
+            'new_password1': 'password1',
+            'new_password2': 'donuts',
+            }
+        )
+        self.assertEquals(response.status_code, 200)
+        self.assert_("The two password fields didn't match." in response.content)
+    
+    def test_password_change_succeeds(self):
+        self.login()
+        response = self.client.post('/password_change/', {
+            'old_password': 'password',
+            'new_password1': 'password1',
+            'new_password2': 'password1',
+            }
+        )
+        self.assertEquals(response.status_code, 302)
+        self.assert_(response['Location'].endswith('/password_change/done/'))
+        self.fail_login()
+        self.login(password='password1')
+        
Index: django/contrib/auth/tests/__init__.py
===================================================================
--- django/contrib/auth/tests/__init__.py	(revision 8471)
+++ django/contrib/auth/tests/__init__.py	(working copy)
@@ -1,11 +1,14 @@
 from django.contrib.auth.tests.basic import BASIC_TESTS
-from django.contrib.auth.tests.views import PasswordResetTest
+from django.contrib.auth.tests.views import PasswordResetTest, ChangePasswordTest
 from django.contrib.auth.tests.forms import FORM_TESTS
 from django.contrib.auth.tests.tokens import TOKEN_GENERATOR_TESTS
 
+# The password for the fixture data users is 'password'
+
 __test__ = {
     'BASIC_TESTS': BASIC_TESTS,
     'PASSWORDRESET_TESTS': PasswordResetTest,
     'FORM_TESTS': FORM_TESTS,
-    'TOKEN_GENERATOR_TESTS': TOKEN_GENERATOR_TESTS
+    'TOKEN_GENERATOR_TESTS': TOKEN_GENERATOR_TESTS,
+    'CHANGEPASSWORD_TESTS': ChangePasswordTest,
 }
Index: django/contrib/auth/tests/templates/registration/login.html
===================================================================
--- django/contrib/auth/tests/templates/registration/login.html	(revision 0)
+++ django/contrib/auth/tests/templates/registration/login.html	(revision 0)
@@ -0,0 +1 @@
+{{ form.as_ul }}
\ No newline at end of file
Index: django/contrib/auth/urls.py
===================================================================
--- django/contrib/auth/urls.py	(revision 8471)
+++ django/contrib/auth/urls.py	(working copy)
@@ -5,6 +5,7 @@
 from django.conf.urls.defaults import *
 
 urlpatterns = patterns('',
+    (r'^login/$', 'django.contrib.auth.views.login'),
     (r'^logout/$', 'django.contrib.auth.views.logout'),
     (r'^password_change/$', 'django.contrib.auth.views.password_change'),
     (r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
