diff --git a/django/test/client.py b/django/test/client.py
index 5cbc0ca..95085b5 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -345,6 +345,7 @@ class Client(RequestFactory):
         super(Client, self).__init__(**defaults)
         self.handler = ClientHandler(enforce_csrf_checks)
         self.exc_info = None
+        self._session_store = None
 
     def store_exc_info(self, **kwargs):
         """
@@ -356,15 +357,25 @@ class Client(RequestFactory):
         """
         Obtains the current session variables.
         """
+        if self._session_store:
+            return self._session_store
+
         if 'django.contrib.sessions' in settings.INSTALLED_APPS:
             engine = import_module(settings.SESSION_ENGINE)
-            cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
+            cookie = self.cookies.get(settings.SESSION_COOKIE_NAME)
             if cookie:
-                return engine.SessionStore(cookie.value)
-        return {}
+                session_store = engine.SessionStore(cookie.value)
+            else:
+                session_store = engine.SessionStore()
+                session_store.save()
+                self.cookies[settings.SESSION_COOKIE_NAME] = \
+                     session_store.session_key
+            self._session_store = session_store
+            return session_store
+        else:
+            return {}
     session = property(_session)
 
-
     def request(self, **request):
         """
         The master request method. Composes the environment dictionary
@@ -374,6 +385,18 @@ class Client(RequestFactory):
         """
         environ = self._base_environ(**request)
 
+        if self._session_store:
+            if getattr(self._session_store, "modified"):
+                self._session_store.save()
+
+            if 'django.contrib.sessions' in settings.INSTALLED_APPS:
+                # Update the session cookie since the session key can change
+                # due to login or logout and force the session to be reloaded
+                # on next access.
+                self.cookies[settings.SESSION_COOKIE_NAME] = \
+                    self._session_store.session_key
+                self._session_store = None
+
         # Curry a data dictionary into an instance of the template renderer
         # callback function.
         data = {}
@@ -505,14 +528,10 @@ class Client(RequestFactory):
         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)
 
             # Save the session values.
@@ -545,6 +564,7 @@ class Client(RequestFactory):
         if session_cookie:
             session.delete(session_key=session_cookie.value)
         self.cookies = SimpleCookie()
+        self._session_store = None
 
     def _handle_redirects(self, response, **extra):
         "Follows any redirects by requesting responses from the server using GET."
diff --git a/docs/topics/testing.txt b/docs/topics/testing.txt
index fb9f6e5..1014b74 100644
--- a/docs/topics/testing.txt
+++ b/docs/topics/testing.txt
@@ -1000,14 +1000,14 @@ can access these properties as part of a test condition.
     A dictionary-like object containing session information. See the
     :doc:`session documentation</topics/http/sessions>` for full details.
 
-    To modify the session and then save it, it must be stored in a variable
-    first (because a new ``SessionStore`` is created every time this property
-    is accessed)::
+.. versionadded:: 1.4
+
+    Similar to normal Django sessions, you can manipulate sessions directly.
+    The modified values will be saved on subsequent requests.
 
         def test_something(self):
-            session = self.client.session
-            session['somekey'] = 'test'
-            session.save()
+            self.client.session['somekey'] = value
+            self.client.session['anotherkey'] = value
 
 .. _Cookie module documentation: http://docs.python.org/library/cookie.html
 
diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py
index 6757695..40848a1 100644
--- a/tests/regressiontests/test_client_regress/models.py
+++ b/tests/regressiontests/test_client_regress/models.py
@@ -691,6 +691,39 @@ class SessionTests(TestCase):
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.content, 'YES')
 
+    def test_session_manipulation(self):
+        # Check that the session can be edited as documented before #10899.
+        session = self.client.session
+        session["session_var"] = "foo"
+        session.save()
+
+        response = self.client.get('/test_client_regress/check_session/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, 'foo')
+
+    def test_direct_session_manipulation(self):
+        # Add a value to the session
+        self.client.session['session_var'] = 'bar'
+        self.assertEqual(self.client.session['session_var'], 'bar')
+
+        # Check that the session has been modified
+        response = self.client.get('/test_client_regress/check_session/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, 'bar')
+
+        # Check that the session variable persists over login
+        # when cycle_key() is called
+        self.client.login(username='testclient', password='password')
+        self.assertEqual(self.client.session['session_var'], 'bar')
+
+        response = self.client.get('/test_client_regress/check_session/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, 'bar')
+
+        # Check that new session is started after logout
+        self.client.logout()
+        self.assertEqual(self.client.session.get('session_var'), None)
+
     def test_logout(self):
         """Logout should work whether the user is logged in or not (#9978)."""
         self.client.logout()
@@ -699,6 +732,7 @@ class SessionTests(TestCase):
         self.client.logout()
         self.client.logout()
 
+
 class RequestMethodTests(TestCase):
     def test_get(self):
         "Request a view via request method GET"
