diff --git a/pytest.ini b/pytest.ini
index 5ee3d35dc215f1e2343609d892d7e574504d7e98..abdd410e5f9e9835a3233b22687ad49cc1109235 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,2 +1,3 @@
 [pytest]
-testpaths = unittests
\ No newline at end of file
+testpaths = unittests
+addopts = -vv --cov=caosdb
diff --git a/setup.cfg b/setup.cfg
index 208d7f783324f2159b24acb8b925f3cb12b9cbc5..74c5620b86c6fd5ee96abea95dab4010c9fb87a3 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,12 +1,2 @@
-[nosetests]
-verbosity=2
-detailed-errors=1
-with-coverage=1
-cover-package=caosdb
-cover-inclusive=1
-cover-branches=1
-cover-erase=1
-#with-doctest=1
-
 [pycodestyle]
 ignore=E501,E121,E123,E126,E226,E24,E704,W503,W504
diff --git a/setup.py b/setup.py
index b9d76430c84d3625c8445c503d45d75966948cc9..f80c619591a55190d70ee105b0cff2e3d79894c1 100755
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-#!/bin/python
+#!/usr/bin/env python
 # -*- encoding: utf-8 -*-
 #
 # ** header v3.0
@@ -35,5 +35,5 @@ setup(name='PyCaosDB',
       install_requires=['lxml>=3.6.4', 'coverage>=4.4.2',
                         'PyYaml>=3.12', 'future'],
       extras_require={'keyring': ['keyring>=13.0.0']},
-      tests_require=["nose>=1.0"],
+      tests_require=["pytest"],
       )
diff --git a/src/caosdb/common/models.py b/src/caosdb/common/models.py
index 5052cc1bea1845ad68984514980f4b2c243e52e9..8c32b94877d38b52caeed722c4b9821033f82cdf 100644
--- a/src/caosdb/common/models.py
+++ b/src/caosdb/common/models.py
@@ -1923,7 +1923,7 @@ class Container(list):
         inserted/updated/deleted/retrieved at once."""
         list.__init__(self)
         self._timestamp = None
-        self._session = None
+        self._srid = None
         self.messages = _Messages()
 
     def extend(self, entities):
@@ -2115,7 +2115,7 @@ class Container(list):
                     # ignore
                     pass
             c._timestamp = xml.get("timestamp")
-            c._session = xml.get("srid")
+            c._srid = xml.get("srid")
             return c
         else:
             raise CaosDBException(
@@ -2160,7 +2160,7 @@ class Container(list):
             self.add_message(m)
 
         self._timestamp = container._timestamp
-        self._session = container._session
+        self._srid = container._srid
 
     def _calc_sync_dict(self, remote_container, unique,
                         raise_exception_on_error, name_case_sensitive):
diff --git a/src/caosdb/connection/authentication/interface.py b/src/caosdb/connection/authentication/interface.py
index d3512174c405f0d86bc4edc11ca10962936f3093..975c43a4b8070944ec4a33fb2993a27b3047f3cb 100644
--- a/src/caosdb/connection/authentication/interface.py
+++ b/src/caosdb/connection/authentication/interface.py
@@ -31,7 +31,7 @@ except ImportError:
     from urllib import quote
 from caosdb.connection.utils import urlencode
 from caosdb.connection.interface import CaosDBServerConnection
-from caosdb.connection.utils import parse_session_token
+from caosdb.connection.utils import parse_auth_token
 from caosdb.exceptions import LoginFailedException
 
 # meta class compatible with Python 2 *and* 3:
@@ -53,10 +53,15 @@ class AbstractAuthenticator(ABC):
     configure
     on_request
     on_response
+
+    Attributes
+    ----------
+    auth_token : str
+        A string representation of a CaosDB Auth Token.
     """
 
     def __init__(self):
-        self._session_token = None
+        self.auth_token = None
 
     @abstractmethod
     def login(self):
@@ -113,7 +118,7 @@ class AbstractAuthenticator(ABC):
         Returns
         -------
         """
-        self._session_token = parse_session_token(
+        self.auth_token = parse_auth_token(
             response.getheader("Set-Cookie"))
 
     def on_request(self, method, path, headers, **kwargs):
@@ -137,8 +142,8 @@ class AbstractAuthenticator(ABC):
         Returns
         -------
         """
-        if self._session_token is not None:
-            headers['Cookie'] = self._session_token
+        if self.auth_token is not None:
+            headers['Cookie'] = self.auth_token
 
 
 class CredentialsAuthenticator(AbstractAuthenticator):
@@ -165,7 +170,7 @@ class CredentialsAuthenticator(AbstractAuthenticator):
         super(CredentialsAuthenticator, self).__init__()
         self._credentials_provider = credentials_provider
         self._connection = None
-        self._session_token = None
+        self._auth_token = None
 
     def login(self):
         self._login()
@@ -175,9 +180,9 @@ class CredentialsAuthenticator(AbstractAuthenticator):
 
     def _logout(self):
         _LOGGER.debug("[LOGOUT]")
-        if self._session_token is not None:
+        if self._auth_token is not None:
             self._connection.request(method="DELETE", path="logout")
-        self._session_token = None
+        self._auth_token = None
 
     def _login(self):
         username = self._credentials_provider.username
diff --git a/src/caosdb/connection/connection.py b/src/caosdb/connection/connection.py
index faa66297c027bcddea9fb8ae5a1939e12c7678d5..9c35e7cf5997854dfff97e7de8822461e5708d89 100644
--- a/src/caosdb/connection/connection.py
+++ b/src/caosdb/connection/connection.py
@@ -37,7 +37,8 @@ import logging
 from caosdb.exceptions import (CaosDBException, LoginFailedException,
                                AuthorizationException, URITooLongException,
                                ConnectionException, ServerErrorException,
-                               EntityDoesNotExistError, ClientErrorException)
+                               EntityDoesNotExistError, ClientErrorException,
+                               ConfigurationException)
 from caosdb.configuration import get_config
 from .utils import urlencode, make_uri_path, parse_url
 from .interface import CaosDBServerConnection, CaosDBHTTPResponse
@@ -256,12 +257,34 @@ class _Connection(object):  # pylint: disable=useless-object-inheritance
             cls.__instance = _Connection()
         return cls.__instance
 
-    def configure(self, **kwargs):
+    def configure(self, **config):
         self.is_configured = True
-        self._delegate_connection = kwargs.get("implementation")()
-        self._delegate_connection.configure(**kwargs)
+        if "implementation" not in config:
+            raise ConfigurationException(
+                "Missing CaosDBServerConnection implementation. You did not "
+                "specify an `implementation` for the connection.")
+        try:
+            self._delegate_connection = config["implementation"]()
+            if not isinstance(self._delegate_connection,
+                              CaosDBServerConnection):
+                raise TypeError("The `implementation` callable did not return "
+                                "an instance of CaosDBServerConnection.")
+        except TypeError as type_err:
+            raise ConfigurationException(
+                "Bad CaosDBServerConnection implementation. The "
+                "implementation must be a callable object which returns an "
+                "instance of `CaosDBServerConnection` (e.g. a constructor "
+                "or a factory).", type_err)
+        self._delegate_connection.configure(**config)
+        if "password_method" not in config:
+            raise ConfigurationException("Missing password_method. You did "
+                                         "not specify a `password_method` for"
+                                         "the connection.")
         self._authenticator = _get_authenticator(
-            connection=self._delegate_connection, **kwargs)
+            connection=self._delegate_connection, **config)
+        if "auth_token" in config:
+            self._authenticator.auth_token = config["auth_token"]
+
         return self
 
     def retrieve(self, entity_uri_segments=None, query_dict=None, **kwargs):
diff --git a/src/caosdb/connection/utils.py b/src/caosdb/connection/utils.py
index 57581f90eac7c8ac68bdaac3e1cf1d697ed31e6c..dfee2383b724fba91bd0ead9746b0d541a950244 100644
--- a/src/caosdb/connection/utils.py
+++ b/src/caosdb/connection/utils.py
@@ -164,11 +164,11 @@ def check_python_ssl_version(hexversion):
         )
 
 
-def parse_session_token(cookie):
-    session_token = None
+def parse_auth_token(cookie):
+    auth_token = None
     if cookie is not None:
         try:
-            session_token = re.compile(r";\s*.*$").split(cookie)[0]
+            auth_token = re.compile(r";\s*.*$").split(cookie)[0]
         except IndexError:
             pass
-    return session_token
+    return auth_token
diff --git a/src/caosdb/exceptions.py b/src/caosdb/exceptions.py
index 581acc2cb4a447c423309f66e2a8ae218cb1a7c0..a5d6e99662c38e6f74e2e974a68ce8152997e271 100644
--- a/src/caosdb/exceptions.py
+++ b/src/caosdb/exceptions.py
@@ -28,11 +28,38 @@ from lxml import etree
 class CaosDBException(Exception):
     """Base class of all CaosDB exceptions."""
 
-    def __init__(self, msg=None):
-        Exception.__init__(self, msg)
+    def __init__(self, msg=None, *args):
+        Exception.__init__(self, msg, *args)
         self.msg = msg
 
 
+class ConfigurationException(CaosDBException):
+    """ConfigurationException.
+
+    Indicates a misconfiguration.
+
+    Parameters
+    ----------
+    msg : str
+        A descriptin of the misconfiguration. The constructor adds
+        a few lines with explainingg where to find the configuration.
+    *args
+
+    Attributes
+    ----------
+    msg : str
+        A description of the misconfiguration.
+    """
+
+    def __init__(self, msg, *args):
+        super(ConfigurationException, self).__init__(msg +
+                                                     ConfigurationException._INFO,
+                                                     *args)
+
+    _INFO = ("\n\nPlease check your ~/.pycaosdb.ini and your $PWD/"
+             ".pycaosdb.ini. Do at least one of them exist and are they correct?")
+
+
 class ClientErrorException(CaosDBException):
     def __init__(self, msg, status, body):
         self.status = status
diff --git a/tox.ini b/tox.ini
index 5a7cee258b4936038d36d59cadd38534bbe7c941..74d8c643c735b0ad287e36aa1841bf8a6f5d328c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -3,4 +3,6 @@ envlist= py27, py34, py35, py36
 skip_missing_interpreters = true
 [testenv]
 deps=nose
-commands= nosetests {posargs}
+    pytest
+    pytest-cov
+commands=py.test --cov=caosdb -vv {posargs}
diff --git a/unittests/test_connection.py b/unittests/test_connection.py
index b25b56214f47aa494607589b6265f7180b1e10ba..3bc6957e2f82e4951c1f0cbccfb20e49efef59bf 100644
--- a/unittests/test_connection.py
+++ b/unittests/test_connection.py
@@ -26,9 +26,11 @@
 from __future__ import unicode_literals, print_function
 from builtins import bytes, str  # pylint: disable=redefined-builtin
 import re
+from pytest import raises
 from nose.tools import (assert_equal as eq, assert_raises as raiz, assert_true
                         as tru, assert_is_not_none as there, assert_false as
                         falz)
+from caosdb.exceptions import ConfigurationException, LoginFailedException
 from caosdb.connection.utils import urlencode, make_uri_path, quote
 from caosdb.connection.connection import (
     configure_connection, CaosDBServerConnection,
@@ -196,19 +198,70 @@ def test_request_basics():
 def setup_two_resources():
     def r1(**kwargs):
         if kwargs["method"] == "GET":
-            return MockUpResponse(status=123, headers={}, body="response r1")
+            return MockUpResponse(status=200, headers=kwargs["headers"], body="response r1")
 
     def r2(**kwargs):
         if kwargs["path"] == "matching/path/":
             return MockUpResponse(
                 status=456, headers={"key": "val"}, body="response r2")
 
+    def r3(**kwargs):
+        if kwargs["path"] == "401":
+            return MockUpResponse(
+                status=401, headers={}, body="please login")
+
     connection = test_init_connection()
-    connection.resources.extend([r1, r2])
+    connection.resources.extend([r1, r2, r3])
     return connection
 
 
 def test_test_request_with_two_responses():
     connection = setup_two_resources()
-    eq(connection.request(method="GET", path="any").status, 123)
+    eq(connection.request(method="GET", path="any", headers={}).status, 200)
     eq(connection.request(method="POST", path="matching/path/").status, 456)
+
+
+def test_missing_implementation():
+    connection = configure_connection()
+    with raises(ConfigurationException) as exc_info:
+        connection.configure()
+    assert exc_info.value.args[0].startswith(
+        "Missing CaosDBServerConnection implementation.")
+
+
+def test_bad_implementation_not_callable():
+    connection = configure_connection()
+    with raises(ConfigurationException) as exc_info:
+        connection.configure(implementation="str")
+    assert exc_info.value.args[0].startswith(
+        "Bad CaosDBServerConnection implementation.")
+    assert exc_info.value.args[1].args[0] == "'str' object is not callable"
+
+
+def test_bad_implementation_wrong_class():
+    connection = configure_connection()
+    with raises(ConfigurationException) as exc_info:
+        connection.configure(implementation=dict)
+    assert exc_info.value.args[0].startswith(
+        "Bad CaosDBServerConnection implementation.")
+    assert exc_info.value.args[1].args[0] == (
+        "The `implementation` callable did not return an instance of "
+        "CaosDBServerConnection.")
+
+
+def test_missing_auth_method():
+    connection = configure_connection()
+    with raises(ConfigurationException) as exc_info:
+        connection.configure(implementation=MockUpServerConnection)
+    assert exc_info.value.args[0].startswith("Missing password_method.")
+
+
+def test_missing_password():
+    connection = configure_connection()
+    connection.configure(implementation=setup_two_resources,
+                         password_method="plain", auth_token="test-auth-token")
+    assert connection.retrieve(["some"]).headers["Cookie"] == "test-auth-token"
+    connection.configure(implementation=setup_two_resources,
+                         password_method="plain")
+    with raises(LoginFailedException):
+        connection.delete(["401"])