Index: test/client.py
===================================================================
--- test/client.py	(revision 10620)
+++ test/client.py	(working copy)
@@ -166,6 +166,7 @@ class Client(object):
         self.cookies = SimpleCookie()
         self.exc_info = None
         self.errors = StringIO()
+        self._session_store = None
 
     def store_exc_info(self, **kwargs):
         """
@@ -175,15 +176,39 @@ class Client(object):
 
     def _session(self):
         """
-        Obtains the current session variables.
+        Obtains a SessionStore containing all the current session variables.
         """
-        if 'django.contrib.sessions' in settings.INSTALLED_APPS:
-            engine = import_module(settings.SESSION_ENGINE)
-            cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
-            if cookie:
-                return engine.SessionStore(cookie.value)
-        return {}
-    session = property(_session)
+        if self._session_store == None:
+            if 'django.contrib.sessions' in settings.INSTALLED_APPS:
+                cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
+                engine = import_module(settings.SESSION_ENGINE)
+                if cookie:
+                    self._session_store = engine.SessionStore(cookie.value)
+                else:
+                    self._session_store = engine.SessionStore()
+                    # if load() fails the cookie changes, so save() first
+                    self._session_store.save()  
+                    self.cookies[settings.SESSION_COOKIE_NAME] = \
+                         self._session_store.session_key
+            else:
+                self._session_store = {}
+        return self._session_store
+    def _failure(self, *extra):
+        assert False, "Don't replace the session store."
+    session = property(_session, _failure, _failure)
+
+    def _session_save(self):
+        """
+        Push the session store to the database then delete the 
+        session store.  It's needed before calling a view.
+        """
+        if hasattr(self._session_store, 'modified'):
+            if self._session_store.modified:
+                self._session_store.save()
+                # update the cookie in case cycle_key() was called
+                self.cookies[settings.SESSION_COOKIE_NAME] = \
+                     self._session_store.session_key
+            self._session_store = None
 
     def request(self, **request):
         """
@@ -268,6 +293,7 @@ class Client(object):
         """
         Requests a response from the server using GET.
         """
+        self._session_save()
         parsed = urlparse(path)
         r = {
             'CONTENT_TYPE':    'text/html; charset=utf-8',
@@ -288,6 +314,7 @@ class Client(object):
         """
         Requests a response from the server using POST.
         """
+        self._session_save()
         if content_type is MULTIPART_CONTENT:
             post_data = encode_multipart(BOUNDARY, data)
         else:
@@ -319,6 +346,7 @@ class Client(object):
         """
         Request a response from the server using HEAD.
         """
+        self._session_save()
         parsed = urlparse(path)
         r = {
             'CONTENT_TYPE':    'text/html; charset=utf-8',
@@ -338,6 +366,7 @@ class Client(object):
         """
         Request a response from the server using OPTIONS.
         """
+        self._session_save()
         parsed = urlparse(path)
         r = {
             'PATH_INFO':       urllib.unquote(parsed[2]),
@@ -357,6 +386,7 @@ class Client(object):
         """
         Send a resource to the server using PUT.
         """
+        self._session_save()
         if content_type is MULTIPART_CONTENT:
             post_data = encode_multipart(BOUNDARY, data)
         else:
@@ -382,6 +412,7 @@ class Client(object):
         """
         Send a DELETE request to the server.
         """
+        self._session_save()
         parsed = urlparse(path)
         r = {
             'PATH_INFO':       urllib.unquote(parsed[2]),
@@ -407,31 +438,11 @@ class Client(object):
         user = authenticate(**credentials)
         if user and user.is_active \
                 and 'django.contrib.sessions' in settings.INSTALLED_APPS:
-            engine = import_module(settings.SESSION_ENGINE)
-
             # Create a fake request to store login details.
             request = HttpRequest()
-            if self.session:
-                request.session = self.session
-            else:
-                request.session = engine.SessionStore()
+            request.session = self.session
             login(request, user)
 
-            # Set the cookie to represent the session.
-            session_cookie = settings.SESSION_COOKIE_NAME
-            self.cookies[session_cookie] = request.session.session_key
-            cookie_data = {
-                'max-age': None,
-                'path': '/',
-                'domain': settings.SESSION_COOKIE_DOMAIN,
-                'secure': settings.SESSION_COOKIE_SECURE or None,
-                'expires': None,
-            }
-            self.cookies[session_cookie].update(cookie_data)
-
-            # Save the session values.
-            request.session.save()
-
             return True
         else:
             return False
@@ -442,6 +453,7 @@ class Client(object):
 
         Causes the authenticated user to be logged out.
         """
+        self._session_store = None
         session = import_module(settings.SESSION_ENGINE).SessionStore()
         session_cookie = self.cookies.get(settings.SESSION_COOKIE_NAME)
         if session_cookie:
