diff --git a/.docker/Dockerfile b/.docker/Dockerfile
index 3dd4b6b0c462d04218e913d683e88a26f1400189..14a4f121954591a255cbb32301f3bad748771f74 100644
--- a/.docker/Dockerfile
+++ b/.docker/Dockerfile
@@ -9,7 +9,6 @@ RUN apt-get update && \
     tox \
     -y
 COPY .docker/wait-for-it.sh /wait-for-it.sh
-ARG PYLIB=dev
 ADD https://gitlab.indiscale.com/api/v4/projects/97/repository/commits/${PYLIB} \
     pylib_version.json
 RUN git clone https://gitlab.indiscale.com/caosdb/src/caosdb-pylib.git && \
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5d821d4a48561444b959fccc397101b1a2d293ed..b2598bd6341ddc6e982820c16705947b972edcf3 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -21,9 +21,9 @@
 variables:
    CI_REGISTRY_IMAGE: $CI_REGISTRY/caosdb/src/caosdb-pyinttest/testenv:$CI_COMMIT_REF_NAME
    CI_REGISTRY_IMAGE_BASE: $CI_REGISTRY/caosdb/src/caosdb-pyinttest/base:latest
-   DEPLOY_REF: dev
 
 stages:
+  - info
   - setup
   - cert
   - style
@@ -79,10 +79,44 @@ stages:
 # file-system features.
 #
 
+.env: &env
+  - echo "Pipeline triggered by $TRIGGERED_BY_REPO@$TRIGGERED_BY_REF ($TRIGGERED_BY_HASH)"
+  - echo "CI_REGISTRY_IMAGE_BASE = $CI_REGISTRY_IMAGE_BASE"
+  - echo "CI_REGISTRY_IMAGE = $CI_REGISTRY_IMAGE"
+  - echo "CAOSDB_TAG = $CAOSDB_TAG"
+  - echo "REFTAG = $REFTAG"
+  - echo "F_BRANCH = $F_BRANCH"
+  - echo "CI_COMMIT_REF_NAME = $CI_COMMIT_REF_NAME"
+  - ls -lah /image-cache/
+
+  - F_BRANCH=${F_BRANCH:-$CI_COMMIT_REF_NAME}
+  - echo $F_BRANCH
+  - if [[ "$REFTAG" == "" ]] ; then
+      if [[ "$F_BRANCH" == "dev" ]] ; then
+        REFTAG=dev;
+      fi;
+    fi
+  - REFTAG=${REFTAG:-dev_F_${F_BRANCH}}
+
+  - echo $F_BRANCH
+
+  - if [[ "$CAOSDB_TAG" == "" ]]; then
+      CAOSDB_TAG=${REFTAG};
+    fi
+  - echo $CAOSDB_TAG
+
+info:
+  tags: [cached-dind]
+  image: docker:20.10
+  stage: info
+  needs: []
+  script:
+    - *env
+
 test:
   tags: [docker]
   services:
-    - docker:20.10.3-dind
+    - docker:20.10-dind
   variables:
     # This is a workaround for the gitlab-runner health check mechanism when
     # using docker-dind service.  The runner will otherwise guess the port
@@ -90,35 +124,10 @@ test:
     SERVICE_PORT_2376_TCP_PORT: 2375
   stage: test
   image: $CI_REGISTRY_IMAGE_BASE
-  needs: ["cert"]
+  needs: [cert]
   script:
-      - echo $F_BRANCH
-      - echo $CAOSDB_TAG
-      - echo $CI_COMMIT_REF_NAME
-      - F_BRANCH=${F_BRANCH:-$CI_COMMIT_REF_NAME}
-      - echo $F_BRANCH
-      - echo $CAOSDB_TAG
-      - echo $CI_COMMIT_REF_NAME
-      - if echo "$F_BRANCH" | grep -c "^f-.*$"; then
-          REFTAG="${REFTAG}_F_${F_BRANCH}";
-        elif [ "$F_BRANCH" == "main" ]; then
-          F_BRANCH=main;
-        else
-          F_BRANCH=dev;
-        fi
-      - echo $F_BRANCH
-      - echo $CI_COMMIT_REF_NAME
-      - echo $CI_REGISTRY_IMAGE
-
+      - *env
       - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
-      - if [[ "$CAOSDB_TAG" == "" ]]; then
-          if echo "$F_BRANCH" | grep -c "^f-" ; then
-            CAOSDB_TAG=${DEPLOY_REF}_F_${F_BRANCH};
-            docker pull $CI_REGISTRY/caosdb/src/caosdb-deploy:$CAOSDB_TAG || CAOSDB_TAG=${DEPLOY_REF} ;
-          else
-            CAOSDB_TAG=${DEPLOY_REF};
-          fi;
-        fi
       - echo $CAOSDB_TAG
 
       - cd .docker
@@ -126,10 +135,10 @@ test:
       - MARIADBVERSION=$(grep mariadb docker-compose.yml | awk '{print $2}')
       - echo "mariadb image:"$MARIADBVERSION
       - time docker load < /image-cache/caosdb-pyint-testenv-${CI_COMMIT_REF_NAME}.tar || true
-      - time docker load < /image-cache/caosdb-${F_BRANCH}.tar || true
+      - time docker load < /image-cache/caosdb-${REFTAG}.tar || time docker load < /image-cache/caosdb-dev.tar || true
       - time docker load < /image-cache/$MARIADBVERSION.tar || true
+      - docker pull $CI_REGISTRY/caosdb/src/caosdb-deploy:$CAOSDB_TAG || CAOSDB_TAG=dev
       - docker pull $CI_REGISTRY_IMAGE
-      - docker pull $CI_REGISTRY/caosdb/src/caosdb-deploy:$CAOSDB_TAG || CAOSDB_TAG=dev ;
 
         # Here, the server and the mysql backend docker are being started
       - CAOSDB_TAG=$CAOSDB_TAG docker-compose  up -d
@@ -139,7 +148,12 @@ test:
       - docker exec -u 0 -t docker_caosdb-server_1 cat /opt/caosdb/git/caosdb_webui_commit > hash_webui
       - docker exec -u 0 -t docker_caosdb-server_1 cat /opt/caosdb/git/caosdb_server_commit > hash_server
       - docker exec -u 0 -t docker_caosdb-server_1 cat /opt/caosdb/git/caosdb_mysqlbackend_commit > hash_mysql
-
+      - docker exec -u 0 -t docker_caosdb-server_1 cat /opt/caosdb/git/caosdb_proto_commit > hash_proto
+      - cat hash_server
+      - cat hash_proto
+      - cat hash_mysql
+      - cat hash_webui
+      - cat hash_pylib
         # Run the actual tests. This starts a new docker container within which
         # the tests run. The return value is stored in .docker/result
       - /bin/sh ./run.sh
@@ -154,8 +168,8 @@ test:
 
         # Store mariadb image
       - if [ ! -f ".gistlab-ci.yml" ]; then
-           time docker save $MARIADBVERSION > /image-cache/$MARIADBVERSION.tar || true
-        fi
+           time docker save $MARIADBVERSION > /image-cache/$MARIADBVERSION.tar || true;
+        fi;
 
         # the pyinttest docker writes the return value of the tests into the
         # file result
@@ -164,7 +178,6 @@ test:
   dependencies: [cert]
   timeout: 3h
   artifacts:
-    when: on_failure
     paths:
       - caosdb_log.txt
       - mariadb_log.txt
@@ -173,7 +186,7 @@ test:
 
 build-testenv:
   tags: [cached-dind]
-  image: docker:19.03
+  image: docker:20.10
   stage: setup
   timeout: 2h
   only:
@@ -212,6 +225,9 @@ cert:
   tags: [docker]
   stage: cert
   image: $CI_REGISTRY_IMAGE
+  needs:
+    - job: build-testenv
+      optional: true
   artifacts:
     paths:
       - .docker/cert/
@@ -219,10 +235,14 @@ cert:
   script:
       - cd .docker
       - CAOSHOSTNAME=caosdb-server ./cert.sh
+
 style:
   tags: [docker]
   stage: style
   image: $CI_REGISTRY_IMAGE
+  needs:
+    - job: build-testenv
+      optional: true
   script:
       - autopep8 -r --diff --exit-code .
   allow_failure: true
diff --git a/.gitlab/merge_request_templates/Default.md b/.gitlab/merge_request_templates/Default.md
deleted file mode 100644
index 77a95da1cc40c815e4952a1283d345af56e80461..0000000000000000000000000000000000000000
--- a/.gitlab/merge_request_templates/Default.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Summary
-
-    Insert a meaningful description for this merge request here.  What is the
-    new/changed behavior? Which bug has been fixed? Are there related Issues?
-
-# Focus
-
-    Point the reviewer to the core of the code change. Where should they start
-    reading? What should they focus on (e.g. security, performance,
-    maintainability, user-friendliness, compliance with the specs, finding more
-    corner cases, concrete questions)?
-
-# Test Environment
-
-    How to set up a test environment for manual testing?
-
-# Check List for the Author
-
-Please, prepare your MR for a review. Be sure to write a summary and a
-focus and create gitlab comments for the reviewer. They should guide the
-reviewer through the changes, explain your changes and also point out open
-questions. For further good practices have a look at [our review
-guidelines](https://gitlab.com/caosdb/caosdb/-/blob/dev/REVIEW_GUIDELINES.md)
-
-- [ ] All automated tests pass
-- [ ] Reference related Issues
-- [ ] Up-to-date CHANGELOG.md
-- [ ] Annotations in code (Gitlab comments)
-  - Intent of new code
-  - Problems with old code
-  - Why this implementation?
-
-
-# Check List for the Reviewer
-
-
-- [ ] I understand the intent of this MR
-- [ ] All automated tests pass
-- [ ] Up-to-date CHANGELOG.md
-- [ ] The test environment setup works and the intended behavior is
-  reproducible in the test environment
-- [ ] In-code documentation and comments are up-to-date.
-- [ ] Check: Are there spezifications? Are they satisfied?
-
-For further good practices have a look at [our review guidelines](https://gitlab.com/caosdb/caosdb/-/blob/dev/REVIEW_GUIDELINES.md).
-
-
-/assign me
-/target_branch dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd58edd8e7fa711540aa8e20f981c155c3945711..c997d3e3d77a949be42440117a4fcba538de7926 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
   [caosdb-server#155](https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/155)
   have been resolved.
 * Tests for caosdb-server#154
+* Tests for caosdb-server#217
 * Tests for caosdb-pylib#61
 
 ### Changed (for changes in existing functionality)
diff --git a/Makefile b/Makefile
index 9689f1e3b68d0bd7f501879bcb6c854c0153a88e..d81534bd53fe76e6244a998aa393a6a86f52ac69 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,7 @@ help:
 
 # Run the tests through autopep8.
 autopep8:
-	autopep8 -ri tests
+	autopep8 -ri .
 
 # Meta target to call the other targets.
 all: autopep8 test
diff --git a/pycaosdb.ini.template b/pycaosdb.ini.template
index c94af17ae01408f9d7f24473ce36ce738c75331d..7530d6af2e24d564c3d02b88b3f7dd38eb4de073 100644
--- a/pycaosdb.ini.template
+++ b/pycaosdb.ini.template
@@ -2,28 +2,30 @@
 
 ## This sections must exist in addition to the usual section.
 [IntegrationTests]
-########## Server-side scripting ##################
+########## Server-side scripting paths ##################
 ## These are used by tests of server side scripting. Both paths have
 ## to point to existing directories in which the CaosDB server has the
 ## permissions to create and execute scripts.
 
-# location of the scripting bin dir which is used for the test scripts from the
-# pyinttest's perspective.
+# Location of the scripting bin dir which is used for the test scripts from the
+# pyinttest's perspective.  Probably the scripting/bin dir in the caosdb-server sources.
 #test_server_side_scripting.bin_dir.local=/path/to/scripting/bin
 
-# location of the scripting bin dir which is used for the test scripts from the
+# Location of the scripting bin dir which is used for the test scripts from the
 # server's perspective.
 #test_server_side_scripting.bin_dir.server=/opt/caosdb/git/caosdb-server/scripting/bin
 
-########## Files ##################
+########## Files paths ##################
 ## Used by tests of file handling. Specify the path to an existing
 ## directory in which file tests are performed, once as seen by the
 ## host and once as seen by the server.
 
-# location of the files from the pyinttest (i.e. host) perspective
+# Location of the files from the pyinttest (i.e. host) perspective.  Probably the local extroot
+# path plus `/test_insert_files_in_dir/`.
 #test_files.test_insert_files_in_dir.local=/extroot/test_insert_files_in_dir/
 
-# location of the files from the caosdb server's perspective
+# Location of the files from the caosdb server's perspective.  Probably with the same last
+# component(s) as the local variant (above).
 #test_files.test_insert_files_in_dir.server=/opt/caosdb/mnt/extroot/test_insert_files_in_dir/
 
 ########## Authentication tokens ##################
diff --git a/tests/test_administration.py b/tests/test_administration.py
index 9ecc1360dc537852463c8ab3c2abc945266711e2..6187da465d19db729fbdba9c8e50c51a15ab7b28 100644
--- a/tests/test_administration.py
+++ b/tests/test_administration.py
@@ -26,7 +26,7 @@
 @author: tf
 """
 
-from caosdb import administration as admin
+from caosdb import administration as admin, Info, get_config
 from caosdb.connection.connection import configure_connection, get_connection
 from caosdb.exceptions import (HTTPClientError, HTTPForbiddenError,
                                LoginFailedError, HTTPResourceNotFoundError)
@@ -52,17 +52,18 @@ def setup_module():
 
 def teardown_module():
     switch_to_admin_user()
+    admin.set_server_property("AUTH_OPTIONAL", "FALSE")
     try:
         admin._delete_user(name=test_user)
     except Exception as e:
         print(e)
 
 
-def setup():
+def setup_function(function):
     switch_to_admin_user()
 
 
-def teardown():
+def teardown_function(function):
     switch_to_admin_user()
     try:
         admin._delete_user(name=test_user + "2")
@@ -81,6 +82,8 @@ def switch_to_normal_user():
 
 def switch_to_admin_user():
     configure_connection()
+    assert Info().user_info.name == get_config().get("Connection", "username")
+    assert Info().user_info.roles == ["administration"]
 
 
 def test_get_server_properties():
@@ -99,6 +102,8 @@ def test_set_server_property():
 
 
 def test_insert_role_success():
+    assert Info().user_info.name == get_config().get("Connection", "username")
+    assert Info().user_info.roles == ["administration"]
     assert admin._insert_role(name=test_role, description=test_role_desc)
 
 
@@ -110,6 +115,8 @@ def test_insert_role_failure_permission():
 
 
 def test_insert_role_failure_name_duplicates():
+    assert Info().user_info.name == get_config().get("Connection", "username")
+    assert Info().user_info.roles == ["administration"]
     test_insert_role_success()
     with assert_raises(HTTPClientError) as cm:
         admin._insert_role(name=test_role, description=test_role_desc)
diff --git a/tests/test_affiliation.py b/tests/test_affiliation.py
index 70a619c5662fa6afb0e4bf949afae720322ecbd2..6c7bef617396a738cfa34cba6816578d951b60ec 100644
--- a/tests/test_affiliation.py
+++ b/tests/test_affiliation.py
@@ -27,7 +27,7 @@
 """
 import os
 import caosdb as db
-from nose.tools import nottest, assert_true, assert_equal, with_setup, assert_is_not_none
+from nose.tools import nottest, assert_equal, assert_is_not_none
 from pytest import raises
 
 
@@ -48,7 +48,7 @@ prop_name = "TestPropertyParent"
 file_path = "testfile.dat"
 
 
-def setup():
+def setup_function(function):
     d = db.execute_query("FIND ENTITY WITH ID > 99")
     if len(d) > 0:
         d.delete()
@@ -58,32 +58,29 @@ def setup():
     db.Property(name=prop_name, datatype=db.TEXT).insert()
 
 
-def teardown():
+def teardown_function(function):
     db.execute_query("FIND Test*").delete()
 
 
 def test_affiliation_there():
     par = db.RecordType(name="TestRT1")
     ch = db.Record(name="TestRec").add_parent(par)
-    assert_is_not_none(ch.get_parent("TestRT1"))
-    assert_true(hasattr(ch.get_parent("TestRT1"), "affiliation"))
+    assert ch.get_parent("TestRT1") is not None
+    assert hasattr(ch.get_parent("TestRT1"), "affiliation")
 
 
-@with_setup(setup, teardown)
 def test_rec_rec_is_parthood():
     par = db.Record(name="TestRecordChild").add_parent(
         name=rec_name).insert().get_parent(rec_name)
     assert_equal(par.affiliation, "PARTHOOD")
 
 
-@with_setup(setup, teardown)
 def test_rec_rt_is_instantiation():
     par = db.Record(name="TestRecordChild").add_parent(
         name=recty_name).insert().get_parent(recty_name)
     assert_equal(par.affiliation, "INSTANTIATION")
 
 
-@with_setup(setup, teardown)
 def test_rec_prop_is_invalid():
     with raises(db.TransactionError) as cm:
         db.Record(name="TestRecordChild").add_parent(name=prop_name).insert()
@@ -94,7 +91,6 @@ def test_rec_prop_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_rec_file_is_invalid():
     with raises(db.TransactionError) as cm:
         db.Record(name="TestRecordChild").add_parent(name=file_name).insert()
@@ -103,7 +99,6 @@ def test_rec_file_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_rt_rec_is_invalid():
     with raises(db.TransactionError) as cm:
         db.RecordType(
@@ -114,14 +109,12 @@ def test_rt_rec_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_rt_rt_is_subtyping():
     par = db.RecordType(name="TestRecordTypeChild").add_parent(
         name=recty_name).insert().get_parent(recty_name)
     assert_equal(par.affiliation, "SUBTYPING")
 
 
-@with_setup(setup, teardown)
 def test_rt_prop_is_invalid():
     with raises(db.TransactionError) as cm:
         db.RecordType(
@@ -132,7 +125,6 @@ def test_rt_prop_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_rt_file_is_invalid():
     with raises(db.TransactionError) as cm:
         db.RecordType(
@@ -143,7 +135,6 @@ def test_rt_file_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_prop_rec_is_invalid():
     with raises(db.TransactionError) as cm:
         db.Property(
@@ -155,7 +146,6 @@ def test_prop_rec_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_prop_rt_is_invalid():
     with raises(db.TransactionError) as cm:
         db.Property(
@@ -167,7 +157,6 @@ def test_prop_rt_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_prop_prop_is_subtyping():
     par = db.Property(
         name="TestPropertyChild",
@@ -176,7 +165,6 @@ def test_prop_prop_is_subtyping():
     assert_equal(par.affiliation, "SUBTYPING")
 
 
-@with_setup(setup, teardown)
 def test_prop_file_is_invalid():
     with raises(db.TransactionError) as cm:
         db.Property(
@@ -188,7 +176,6 @@ def test_prop_file_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_file_rec_is_parthood():
     par = db.File(
         name="TestFileChild",
@@ -198,7 +185,6 @@ def test_file_rec_is_parthood():
     assert_equal(par.affiliation, "PARTHOOD")
 
 
-@with_setup(setup, teardown)
 def test_file_rt_is_instantiation():
     par = db.File(
         name="TestFileChild",
@@ -208,7 +194,6 @@ def test_file_rt_is_instantiation():
     assert_equal(par.affiliation, "INSTANTIATION")
 
 
-@with_setup(setup, teardown)
 def test_file_prop_is_invalid():
     with raises(db.TransactionError) as cm:
         db.File(
@@ -221,7 +206,6 @@ def test_file_prop_is_invalid():
     assert ee.msg == "Affiliation is not defined for this child-parent constellation."
 
 
-@with_setup(setup, teardown)
 def test_file_file_is_invalid():
     with raises(db.TransactionError) as cm:
         db.File(
diff --git a/tests/test_authentication.py b/tests/test_authentication.py
index ef0657cbe215743e79ce1e2110a1b172cb980c36..c885523a8ac52b2f2d84a55e92c3351a39edae47 100644
--- a/tests/test_authentication.py
+++ b/tests/test_authentication.py
@@ -41,7 +41,7 @@ from .test_server_side_scripting import request
 _USED_OTA_TOKEN = set()
 
 
-def setup():
+def setup_function(function):
     db.configure_connection()
 
     # deactivate anonymous user
@@ -51,8 +51,8 @@ def setup():
         d.delete()
 
 
-def teardown():
-    setup()
+def teardown_function(function):
+    setup_function(function)
 
 
 @mark.skipif(
diff --git a/tests/test_creation.py b/tests/test_creation.py
index a2a431e82c948286afba71841832025241208d24..5f5d3ecac30c8888ac9f788e45a7dd57ffaa347c 100755
--- a/tests/test_creation.py
+++ b/tests/test_creation.py
@@ -27,17 +27,15 @@
 # A. Schlemmer, 08/2014
 
 from caosdb import Container, RecordType, Property, execute_query
-from nose.tools import with_setup  # @UnresolvedImport
 
 
-def setup():
+def setup_function(function):
     try:
         execute_query("FIND PA_*").delete()
     except BaseException:
         pass
 
 
-@with_setup(setup, setup)
 def test_PA_Datamodel():
     pr10 = Property(name="PA_DataFile", id=-10, datatype="file",
                     description="The property specifying the "
diff --git a/tests/test_datatype.py b/tests/test_datatype.py
index 3abba3f85369df799ed3611b84ce7d54f8dc17f0..46c52108e9bb1aed097c109ea30f675f6efc20a2 100644
--- a/tests/test_datatype.py
+++ b/tests/test_datatype.py
@@ -29,14 +29,14 @@ import caosdb as db
 from pytest import raises
 
 
-def setup():
+def setup_function(function):
     try:
         db.execute_query("FIND Test*").delete()
     except BaseException:
         pass
 
 
-def teardown():
+def teardown_function(function):
     try:
         db.execute_query("FIND Test*").delete()
     except BaseException:
diff --git a/tests/test_datatype_inheritance.py b/tests/test_datatype_inheritance.py
index 638207181dee055a1fcfffa57386e598a32ab828..119f72869612f636346da098630ff8715d888a44 100644
--- a/tests/test_datatype_inheritance.py
+++ b/tests/test_datatype_inheritance.py
@@ -25,18 +25,17 @@ from caosdb import Container, Property, RecordType, Record, execute_query
 import caosdb
 import caosdb as db
 from caosdb.connection.connection import get_connection
-# @UnresolvedImport
-from nose.tools import assert_is_not_none, assert_true, assert_equal, with_setup
+from nose.tools import assert_is_not_none, assert_true, assert_equal
 
 from caosdb.exceptions import TransactionError
 from pytest import raises
 
 
-def setup():
-    teardown()
+def setup_function(function):
+    teardown_function(function)
 
 
-def teardown():
+def teardown_function(function):
     try:
         db.execute_query("FIND test_*").delete()
     except BaseException:
@@ -47,7 +46,6 @@ def teardown():
         pass
 
 
-@with_setup(setup, teardown)
 def test_default_datatype_for_recordtypes():
     rt1 = db.RecordType(name="TestRT1").insert()
     rt2 = db.RecordType(name="TestRT2").add_property(name="TestRT1").insert()
@@ -62,7 +60,6 @@ def test_default_datatype_for_recordtypes():
     assert_equal(p.datatype, rt1.name)
 
 
-@with_setup(setup, teardown)
 def test_datatype_inheritance():
 
     insert = '<Insert><Property id="-1" name="test_property" description="bla" datatype="Text"/><RecordType name="test_rt" description="bla">    <Property id="-1" importance="obligatory" /></RecordType></Insert>'
diff --git a/tests/test_deletion.py b/tests/test_deletion.py
index fd2236ec2b96d0a0340ebb773fc829066f824941..bf449218765e49f994c69eaebff60c6673c0f867 100755
--- a/tests/test_deletion.py
+++ b/tests/test_deletion.py
@@ -26,7 +26,7 @@
 # Testcase fuer deletion
 # A. Schlemmer, 08/2014
 
-from nose.tools import with_setup, assert_false, assert_true, assert_raises, assert_equal, assert_is_not_none  # @UnresolvedImport
+from nose.tools import with_setup, assert_false, assert_true, assert_raises, assert_equal
 
 import caosdb as h
 
@@ -37,18 +37,11 @@ def setup_module():
         old.delete()
 
 
-def setup161():
+def test_delete_referencing_properties():
     h.RecordType(name="RT1").insert()
     h.RecordType(name="RT2").add_property("RT1").insert()
     h.RecordType(name="RT3").insert()
 
-
-def teardown161():
-    setup_module()
-
-
-@with_setup(setup161, teardown161)
-def test_delete_referencing_properties():
     rt3 = h.RecordType(name="RT3").retrieve()
     rt2 = h.RecordType(name="RT2").retrieve()
     rt3.add_property(
@@ -61,14 +54,13 @@ def test_delete_referencing_properties():
     h.execute_query("FIND ENTITY WITH ID > 100").delete()
 
 
-def setup():
+def setup_function(function):
     try:
         h.execute_query("FIND Test*").delete()
     except Exception as e:
         print(e)
 
 
-@with_setup(setup, setup)
 def test_deletion():
     c = h.Container()
     c.append(
@@ -148,7 +140,7 @@ def test_deletion():
 
     cr2.insert()
     assert_true(cr2.is_valid())
-    assert_is_not_none(cr2.id)
+    assert cr2.id is not None
 
     c.extend([cr1, sr, d])
     assert_raises(h.TransactionError, c.delete)
diff --git a/tests/test_empty_text_value.py b/tests/test_empty_text_value.py
index fe705d6deadc7ce57e0a12c3d5492c3ab9b7d87e..64be317878150e735e6d197835381d5a52b22dcc 100644
--- a/tests/test_empty_text_value.py
+++ b/tests/test_empty_text_value.py
@@ -24,15 +24,15 @@ import pytest
 import caosdb as db
 
 
-def setup():
-    teardown()
+def setup_function(function):
+    teardown_function(function)
     rt = db.RecordType("TestRT")
     rt.insert()
     p = db.Property("TestProp", datatype=db.TEXT)
     p.insert()
 
 
-def teardown():
+def teardown_function(function):
     try:
         db.execute_query("FIND Test*").delete()
     except Exception as e:
diff --git a/tests/test_error_stuff.py b/tests/test_error_stuff.py
index d6eb85b74bf288e91de02c4d6d95e1f1298b2c0f..ca33fb2f101ad87e701bad92745490699b1e789a 100644
--- a/tests/test_error_stuff.py
+++ b/tests/test_error_stuff.py
@@ -40,16 +40,16 @@ from caosdb.exceptions import (AmbiguousEntityError,
 import pytest
 
 
-def setup():
+def setup_function(function):
     try:
         h.execute_query("FIND Test*").delete()
     except BaseException:
         pass
 
 
-def teardown():
+def teardown_function(function):
     """Delete everything."""
-    setup()
+    setup_function(function)
 
 
 def test_retrieval_no_exception_raised():
diff --git a/tests/test_file.py b/tests/test_file.py
index 7b24c9777a39b9d6b6ed66540441b09056c36f37..67d9c1ed05c52dd8a77c6b746a7c1c9fe2c71cb4 100644
--- a/tests/test_file.py
+++ b/tests/test_file.py
@@ -43,11 +43,11 @@ from caosdb.utils.checkFileSystemConsistency import runCheck
 
 
 def setup_module():
-    teardown()
+    teardown_function(None)
 
 
-def setup():
-    teardown()
+def setup_function(function):
+    teardown_function(function)
     with open("test.dat", "w") as upload_file:
         upload_file.write("hello world\n")
     os.makedirs("testfolder/subfolder")
@@ -57,7 +57,7 @@ def setup():
         upload_file.write("hello world\n")
 
 
-def teardown():
+def teardown_function(function):
     d = execute_query("FIND ENTITY WHICH HAS AN ID >= 100")
     if len(d) > 0:
         d.delete()
diff --git a/tests/test_importance.py b/tests/test_importance.py
index afa63effa4d70b32728777d3304a09c212c318e1..6bcf4a097647c6d8393192361337e0b45a1417b0 100644
--- a/tests/test_importance.py
+++ b/tests/test_importance.py
@@ -22,7 +22,7 @@ from pytest import raises
 import caosdb as db
 
 
-def setup():
+def setup_function(function):
     teardown_module()
 
 
diff --git a/tests/test_inheritance.py b/tests/test_inheritance.py
index 6b4fd2c293b88d6a3ae241b8302c186b84ac4ebd..bffb128484364906ec2e30342cbc5090c7ca9554 100644
--- a/tests/test_inheritance.py
+++ b/tests/test_inheritance.py
@@ -30,11 +30,11 @@
 import caosdb as db
 
 
-def setup():
-    teardown()
+def setup_function(function):
+    teardown_function(function)
 
 
-def teardown():
+def teardown_function(function):
     d = db.execute_query("FIND ENTITY WITH ID > 99")
     if len(d) > 0:
         d.delete()
diff --git a/tests/test_issues_mysqlbackend.py b/tests/test_issues_mysqlbackend.py
index 64de2f2f6e4d92effc9847598e474bd80a06825d..5904deda1ac5a63f40eeb578ba82cd249ebfcec6 100644
--- a/tests/test_issues_mysqlbackend.py
+++ b/tests/test_issues_mysqlbackend.py
@@ -33,12 +33,12 @@ def setup_module():
         print(delete_exc)
 
 
-def setup():
+def setup_function(function):
     """No setup required."""
     setup_module()
 
 
-def teardown():
+def teardown_function(function):
     """Deleting entities again."""
     setup_module()
 
diff --git a/tests/test_issues_server.py b/tests/test_issues_server.py
index a05a1ca465d6515552213c963d6d3e1211695eb2..e9a93685cfd222000a50b399d44ec32692137e4f 100644
--- a/tests/test_issues_server.py
+++ b/tests/test_issues_server.py
@@ -1,10 +1,8 @@
 # -*- coding: utf-8 -*-
-#
-# ** header v3.0
 # This file is a part of the CaosDB Project.
 #
-# Copyright (c) 2020 IndiScale GmbH <info@indiscale.com>
-# Copyright (c) 2020 Daniel Hornung <d.hornung@indiscale.com>
+# Copyright (c) 2022 IndiScale GmbH <info@indiscale.com>
+# Copyright (c) 2022 Daniel Hornung <d.hornung@indiscale.com>
 # Copyright (c) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com>
 #
 # This program is free software: you can redistribute it and/or modify
@@ -19,8 +17,6 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program. If not, see <https://www.gnu.org/licenses/>.
-#
-# ** end header
 
 """Tests for issues on gitlab.com, project caosdb-server."""
 
@@ -41,15 +37,14 @@ def setup_module():
         print(delete_exc)
 
 
-def setup():
+def setup_function(function):
     """No setup required."""
     setup_module()
 
 
-def teardown():
+def teardown_function(function):
     """Deleting entities again."""
     setup_module()
-    pass
 
 
 # ########################### Issue tests start here #####################
@@ -463,3 +458,249 @@ def test_issue_183():
                     value="2015-05-05T20:15").insert()
     assert cm.value.errors[0].msg == ("Cannot parse value to datetime format "
                                       "(yyyy-mm-dd'T'hh:mm:ss[.fffffffff][TimeZone]).")
+
+
+@pytest.mark.xfail(reason="fix https://gitlab.com/caosdb/caosdb-server/-/issues/130")
+def test_issue_130():
+    """Test select queries where names contain spaces
+
+    https://gitlab.com/caosdb/caosdb-server/-/issues/130
+
+    However, this bug was actually about quotation marks
+    """
+    db.RecordType(name="TestRT_A").insert()
+    r1 = db.Record("ReferencedRecord").add_parent("TestRT_A").insert()
+    p1 = db.Property(name="TestWrapper", datatype="TestRT_A").insert()
+    p2 = db.Property(
+        name="TestWrapper With Spaces",
+        datatype="TestRT_A").insert()
+    db.RecordType(name="TestRT_B"
+                  ).add_property(name="TestWrapper"
+                                 ).add_property("TestWrapper With Spaces"
+                                                ).insert()
+    db.Record().add_parent("TestRT_B"
+                           ).add_property("TestWrapper", value=r1
+                                          ).add_property("TestWrapper With Spaces",
+                                                         value=r1
+                                                         ).insert()
+
+    query = "SELECT TestWrapper FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(("TestWrapper"))
+    assert row == [(r1.id,)]
+
+    query = "SELECT TestWrapper FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(("TestWrapper", "id"))
+    assert row == [(p1.id,)]
+
+    query = "SELECT 'TestWrapper' FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(("TestWrapper", "id"))
+    assert row == [(r1.id,)]  # FAILS
+
+    query = "SELECT TestWrapper FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(("TestWrapper", "name"))
+    assert row == [("TestWrapper",)]
+
+    query = "SELECT TestWrapper.name FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(("TestWrapper", "name"))
+    assert row == [("ReferencedRecord",)]
+
+    query = "SELECT 'TestWrapper.name' FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(("TestWrapper", "name"))
+    assert row == [("ReferencedRecord",)]  # FAILS
+
+    query = "SELECT 'TestWrapper'.name FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(("TestWrapper", "name"))
+    assert row == [("ReferencedRecord",)]  # FAILS
+
+    query = "SELECT TestWrapper With Spaces FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(
+        ("TestWrapper With Spaces"))
+    assert row == [(r1.id,)]
+
+    query = "SELECT TestWrapper With Spaces FROM RECORD TestRT_B"
+    row = db.execute_query(query).get_property_values(
+        ("TestWrapper With Spaces", "id"))
+    assert row == [(p2.id,)]
+
+    query = 'SELECT TestWrapper With Spaces FROM RECORD TestRT_B'
+    row = db.execute_query(query).get_property_values(
+        ("TestWrapper With Spaces", "name"))
+    assert row == [("TestWrapper With Spaces",)]
+
+    query = 'SELECT "TestWrapper With Spaces" FROM RECORD TestRT_B'
+    row = db.execute_query(query).get_property_values(
+        ("TestWrapper With Spaces", "name"))
+    assert row == [("ReferencedRecord",)]  # FAILS
+
+    query = 'SELECT TestWrapper With Spaces.name FROM RECORD TestRT_B'
+    row = db.execute_query(query).get_property_values(
+        ("TestWrapper With Spaces", "name"))
+    # Works!!! This is about the quotation marks
+    assert row == [("ReferencedRecord",)]
+
+    query = 'SELECT "TestWrapper With Spaces.name" FROM RECORD TestRT_B'
+    row = db.execute_query(query).get_property_values(
+        ("TestWrapper With Spaces", "name"))
+    assert row == [("ReferencedRecord",)]  # FAILS
+
+    query = 'SELECT "TestWrapper With Spaces".name FROM RECORD TestRT_B'
+    row = db.execute_query(query).get_property_values(
+        ("TestWrapper With Spaces", "name"))
+    assert row == [("ReferencedRecord",)]  # FAILS
+
+
+def test_issue_132():
+    """Query: Parenthesis around subproperties.
+
+    https://gitlab.com/caosdb/caosdb-server/-/issues/132
+    """
+    db.RecordType("TestRT").insert()
+    db.RecordType("TestRT_Foo").insert()
+    db.Property("TestP_Bar", datatype=db.TEXT).insert()
+    db.Property("TestP_Baz", datatype=db.TEXT).insert()
+
+    rt1 = db.Record().add_parent("TestRT_Foo").add_property(
+        "TestP_Bar", "val1").add_property(
+        "TestP_Baz", "the other baz").insert()
+    rt2 = db.Record().add_parent("TestRT").add_property(
+        "TestP_Baz", "val2").add_property(
+        "TestRT_Foo", rt1).insert()
+
+    query = "FIND RECORD TestRT_Foo"
+    assert db.execute_query(query, unique=True).id == rt1.id
+
+    query = "FIND RECORD TestRT"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    query = "FIND RECORD TestRT WITH TestRT_Foo"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    query = "FIND RECORD TestRT WITH TestRT_Foo.TestP_Bar"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    query = "FIND RECORD TestRT WITH TestRT_Foo.TestP_Bar = val1"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    query = "FIND RECORD TestRT WITH (TestRT_Foo.TestP_Bar = val1)"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    query = "FIND RECORD TestRT WITH ( TestRT_Foo.TestP_Bar = val1 )"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    query = "FIND RECORD TestRT WITH (TestRT_Foo.TestP_Bar = val1) AND TestP_Baz = val2"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    query = "FIND RECORD TestRT WITH (TestRT_Foo WITH (TestP_Bar = val1 AND TestP_Baz = 'the other baz')) AND TestP_Baz = val2"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    query = "FIND RECORD TestRT WITH TestRT_Foo WITH (TestP_Bar = val1 AND TestP_Baz = 'the other baz') AND TestP_Baz = val2"
+    assert db.execute_query(query, unique=True).id == rt2.id
+
+    # this one has the wront scope of the conjunction.
+    query = "FIND RECORD TestRT WITH TestRT_Foo.TestP_Bar = val1 AND TestP_Baz = 'the other one'"
+    assert len(db.execute_query(query)) == 0
+
+
+def test_issue_217():
+    """Server gets list property datatype wrong if description is updated."""
+    # @review Florian Spreckelsen 2022-03-15
+
+    rt = db.RecordType(name="TestRT").insert()
+    # prop = db.Property(name="LP", datatype=db.LIST("TestRT")).insert()
+    r = db.Record().add_parent(id=rt.id).add_property(name=rt.name,
+                                                      datatype=db.LIST(
+                                                          db.INTEGER),
+                                                      value=[10001, 10002])
+    assert r.get_property(rt.name).datatype == db.LIST(db.INTEGER)
+    assert r.get_property(rt.name).value == [10001, 10002]
+    r.insert()
+    assert r.get_property(rt.name).datatype == db.LIST(db.INTEGER)
+    assert r.get_property(rt.name).value == [10001, 10002]
+    r.retrieve()
+    assert r.get_property(rt.name).datatype == db.LIST(db.INTEGER)
+    assert r.get_property(rt.name).value == [10001, 10002]
+    r.retrieve(flags={"cache": "false"})
+    assert r.get_property(rt.name).datatype == db.LIST(db.INTEGER)
+    assert r.get_property(rt.name).value == [10001, 10002]
+    r.description = "Changed description"
+    r.update()
+    assert r.get_property(rt.name).datatype == db.LIST(db.INTEGER)
+    assert r.get_property(rt.name).value == [10001, 10002]
+    # This line fails in the bug report with invalid XML.
+    r.retrieve()
+    assert r.get_property(rt.name).datatype == db.LIST(db.INTEGER)
+    assert r.get_property(rt.name).value == [10001, 10002]
+
+
+def test_issue_217_2():
+    """Server gets overridden name of property wrong when the description of record is being updated."""
+    # @review Florian Spreckelsen 2022-03-15
+
+    rt = db.RecordType(name="TestRT").insert()
+    # prop = db.Property(name="LP", datatype=db.LIST("TestRT")).insert()
+    overridden_name = "TestRT-overridden"
+    r = db.Record().add_parent(id=rt.id).add_property(name=overridden_name,
+                                                      id=rt.id)
+    assert r.get_property(overridden_name) is not None
+    assert r.get_property(overridden_name).id == rt.id
+    r.insert()
+    assert r.get_property(overridden_name) is not None
+    assert r.get_property(overridden_name).id == rt.id
+    r.retrieve()
+    assert r.get_property(overridden_name) is not None
+    assert r.get_property(overridden_name).id == rt.id
+    r.retrieve(flags={"cache": "false"})
+    assert r.get_property(overridden_name) is not None
+    assert r.get_property(overridden_name).id == rt.id
+    r.description = "Changed description"  # change description of the record
+    r.update()
+    assert r.get_property(overridden_name) is not None
+    assert r.get_property(overridden_name).id == rt.id
+    r.retrieve()
+    assert r.get_property(overridden_name) is not None
+    assert r.get_property(overridden_name).id == rt.id
+
+
+def test_issue_217_3():
+    """Server gets overridden description of property wrong when the description of record is being updated."""
+    # @review Florian Spreckelsen 2022-03-15
+
+    rt = db.RecordType(name="TestRT", description="Desc").insert()
+    # prop = db.Property(name="LP", datatype=db.LIST("TestRT")).insert()
+    r = db.Record().add_parent(id=rt.id).add_property(description="Desc-overridden",
+                                                      id=rt.id)
+    r.insert()
+    assert r.get_property(rt.name).id == rt.id
+    assert r.get_property(rt.name).description == "Desc-overridden"
+    r.retrieve()
+    assert r.get_property(rt.name).id == rt.id
+    assert r.get_property(rt.name).description == "Desc-overridden"
+    r.retrieve(flags={"cache": "false"})
+    assert r.get_property(rt.name).id == rt.id
+    assert r.get_property(rt.name).description == "Desc-overridden"
+    r.description = "Changed description"  # change description of the record
+    r.update()
+    assert r.get_property(rt.name).id == rt.id
+    assert r.get_property(rt.name).description == "Desc-overridden"
+    r.retrieve()
+    assert r.get_property(rt.name).id == rt.id
+    assert r.get_property(rt.name).description == "Desc-overridden"
+
+
+def test_issue_221():
+    """Unknown error during update of property leaving out datatype"""
+
+    rt = db.RecordType("A")
+    r = db.Record()
+    r.add_parent(rt)
+    p = db.Property(name="B", datatype=db.INTEGER)
+    r.add_property(name="B", value=5)
+    db.Container().extend([rt, r, p]).insert()
+
+    r2 = db.Record(id=r.id).retrieve()
+    r2.remove_property("B")
+    r2.add_property(p, value=7)
+    r2.update()
+    assert r2.get_property("B").value == 7
+    assert r2.get_property("B").datatype == db.INTEGER
+    assert r2.get_property("B").id == p.id
diff --git a/tests/test_list.py b/tests/test_list.py
index 2888552b3f26770986596f28dde6c87eb4b4271d..63ece67b7b454800533a68b2c86d5db51776be68 100644
--- a/tests/test_list.py
+++ b/tests/test_list.py
@@ -33,16 +33,16 @@ from nose.tools import assert_true, assert_equal
 from pytest import raises
 
 
-def setup():
+def setup_function(function):
     d = db.execute_query("FIND ENTITY WITH ID > 99")
     if len(d) > 0:
         d.delete()
 
 
-def teardown():
+def teardown_function(function):
     if os.path.isfile("test.dat"):
         os.remove("test.dat")
-    setup()
+    setup_function(function)
 
 
 def test_list_of_files():
diff --git a/tests/test_misc.py b/tests/test_misc.py
index 177843a765a83ceb9b4de3f43b1b2caa2e31658d..15ba810887802917725a8eb8e88b6fa66f98c3bf 100644
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -31,7 +31,7 @@ from pytest import raises
 from pytest import mark
 
 
-def setup():
+def setup_function(function):
     try:
         db.execute_query("FIND Test*").delete()
     except Exception as e:
@@ -227,7 +227,7 @@ def test_annotation():
 
 def test_info():
     assert admin.get_server_property(
-        "TRANSACTION_BENCHMARK_ENABLED") == "TRUE", "Please activate the transaction benchmark with the server option TRANSACTION_BENCHMARK_ENABLED=TRUE (Restart of the server needed)"
+        "TRANSACTION_BENCHMARK_ENABLED").lower() == "true", "Please activate the transaction benchmark with the server option TRANSACTION_BENCHMARK_ENABLED=TRUE (Restart of the server needed)"
     i = Info()
     assert (i.messages["Flags"]) is not None
     assert (i.messages["Counts"]) is not None
diff --git a/tests/test_name_properties.py b/tests/test_name_properties.py
index 028592b7c0a728587f9939e427eb40ba74b9be43..c389945d5a46bfa8f22511554a751051ebf625fc 100644
--- a/tests/test_name_properties.py
+++ b/tests/test_name_properties.py
@@ -27,8 +27,8 @@
 """
 
 import caosdb as db
-from pytest import raises, mark
-from nose.tools import nottest, assert_true, assert_raises, assert_equal, with_setup, assert_is_not_none  # @UnresolvedImport
+from pytest import raises
+from nose.tools import assert_true, assert_equal
 
 
 def setup_module():
@@ -36,36 +36,34 @@ def setup_module():
 
 
 def teardown_module():
-    teardown()
+    teardown_function(None)
 
 
-def setup():
+def setup_function(function):
     try:
         db.execute_query("FIND Test*").delete()
     except BaseException:
         pass
 
 
-def teardown():
+def teardown_function(function):
     try:
         db.execute_query("FIND Test*").delete()
     except BaseException:
         pass
 
 
-@with_setup(setup, teardown)
 def test_property_insertion():
     p = db.Property(
         name="TestShortName",
         datatype=db.TEXT,
         value="TestSN").add_parent(
         name="name").insert()
-    assert_true(p.is_valid())
+    assert p.is_valid()
 
     return p
 
 
-@with_setup(setup, teardown)
 def test_property_query():
     pid = test_property_insertion().id
     assert_equal(db.execute_query("FIND TestShortName", unique=True).id, pid)
@@ -74,29 +72,26 @@ def test_property_query():
     assert_equal(len(db.execute_query("FIND TestSN")), 0)
 
 
-@with_setup(setup, teardown)
 def test_recordtype_insertion_separately_prop_by_id_direct_name_child():
     pid = test_property_insertion().id
     rt = db.RecordType(
         name="TestRecordType").add_property(
         id=pid, value="TestRT").insert()
-    assert_true(rt.is_valid())
+    assert rt.is_valid()
 
     return rt
 
 
-@with_setup(setup, teardown)
 def test_recordtype_is_stored_correctly():
     test_recordtype_insertion_separately_prop_by_id_direct_name_child()
 
     rt = db.RecordType(name="TestRecordType").retrieve()
-    assert_true(rt.is_valid())
+    assert rt.is_valid()
     assert_equal(len(rt.get_properties()), 1)
-    assert_is_not_none(rt.get_property("TestShortName"))
+    assert rt.get_property("TestShortName") is not None
     assert_equal(rt.get_property("TestShortName").value, "TestRT")
 
 
-@with_setup(setup, teardown)
 def test_recordtype_insertion_container_prop_by_tempid_direct_name_child():
     p = db.Property(
         name="TestShortName",
@@ -109,13 +104,12 @@ def test_recordtype_insertion_container_prop_by_tempid_direct_name_child():
         id=-1, value="TestRT")
     c = db.Container().extend([p, rt])
     c.insert()
-    assert_true(c.is_valid())
-    assert_true(p.is_valid())
-    assert_true(rt.is_valid())
+    assert c.is_valid()
+    assert p.is_valid()
+    assert rt.is_valid()
     return rt
 
 
-@with_setup(setup, teardown)
 def test_recordtype_insertion_container_prop_by_name_direct_name_child():
     p = db.Property(
         name="TestShortName",
@@ -128,40 +122,37 @@ def test_recordtype_insertion_container_prop_by_name_direct_name_child():
         value="TestRT")
     c = db.Container().extend([p, rt])
     c.insert()
-    assert_true(c.is_valid())
-    assert_true(p.is_valid())
-    assert_true(rt.is_valid())
+    assert c.is_valid()
+    assert p.is_valid()
+    assert rt.is_valid()
     return rt
 
 
-@with_setup(setup, teardown)
 def test_recordtype_insertion_separately_prop_by_name_direct_name_child():
     test_property_insertion()
     rt = db.RecordType(
         name="TestRecordType").add_property(
         name="TestShortName",
         value="TestRT").insert()
-    assert_true(rt.is_valid())
+    assert rt.is_valid()
     return rt
 
 
-@with_setup(setup, teardown)
 def test_recordtpye_insertion_with_indirect_child_with_existing_parent():
     test_property_insertion()
     p = db.Property(
         name="TestExtraShortName").add_parent(
         name="TestShortName").insert()
-    assert_true(p.is_valid())
+    assert p.is_valid()
 
     rt = db.RecordType(
         name="TestRecordType").add_property(
         name="TestExtraShortName",
         value="TestRT").insert()
-    assert_true(rt.is_valid())
+    assert rt.is_valid()
     return rt
 
 
-@with_setup(setup, teardown)
 def test_recordtpye_insertion_with_indirect_child_with_new_parent():
     parp = db.Property(name="TestShortName").add_parent(name="name")
     p = db.Property(name="TestExtraShortName").add_parent(name="TestShortName")
@@ -171,40 +162,39 @@ def test_recordtpye_insertion_with_indirect_child_with_new_parent():
         value="TestRT")
     c = db.Container().extend([parp, p, rt]).insert()
 
-    assert_true(c.is_valid())
-    assert_true(p.is_valid())
-    assert_true(parp.is_valid())
-    assert_true(rt.is_valid())
+    assert c.is_valid()
+    assert p.is_valid()
+    assert parp.is_valid()
+    assert rt.is_valid()
 
     return rt
 
 
-@nottest
-def do_unique_query_test(call, queries):
-    setup()
+def assert_same_unique_results(call, queries):
+    setup_function(None)
     rtid = call().id
     for q in queries:
         assert_equal(db.execute_query(q, unique=True).id, rtid)
-    teardown()
+    teardown_function(None)
 
 
 def test_recordtype_query():
-    do_unique_query_test(
+    assert_same_unique_results(
         test_recordtype_insertion_separately_prop_by_id_direct_name_child, [
             "FIND TestRecordType", "FIND TestRT"])
-    do_unique_query_test(
+    assert_same_unique_results(
         test_recordtype_insertion_separately_prop_by_name_direct_name_child, [
             "FIND TestRecordType", "FIND TestRT"])
-    do_unique_query_test(
+    assert_same_unique_results(
         test_recordtype_insertion_container_prop_by_name_direct_name_child, [
             "FIND TestRecordType", "FIND TestRT"])
-    do_unique_query_test(
+    assert_same_unique_results(
         test_recordtype_insertion_container_prop_by_tempid_direct_name_child, [
             "FIND TestRecordType", "FIND TestRT"])
-    do_unique_query_test(
+    assert_same_unique_results(
         test_recordtpye_insertion_with_indirect_child_with_new_parent, [
             "FIND TestRecordType", "FIND TestRT"])
-    do_unique_query_test(
+    assert_same_unique_results(
         test_recordtpye_insertion_with_indirect_child_with_existing_parent, [
             "FIND TestRecordType", "FIND TestRT"])
 
@@ -224,7 +214,7 @@ def test_query_name_property():
     with raises(db.BadQueryError):
         db.execute_query("FIND John", unique=True)
 
-    teardown()
+    teardown_function(None)
 
     # test behavior WITH the name parent
     db.RecordType("TestPerson").insert()
@@ -239,7 +229,6 @@ def test_query_name_property():
                             unique=True).id == rec.id
 
 
-@with_setup(setup, teardown)
 def test_query_property_with_pov():
     """ Insert a Record with a property which can be searched using two
     different names.
@@ -285,7 +274,6 @@ def test_query_property_with_pov():
         rec.id)
 
 
-@with_setup(setup, teardown)
 def test_query_with_reference():
     """ Insert a Record with two names. Both work in a reference query.
 
@@ -321,7 +309,6 @@ def test_query_with_reference():
         rec.id)
 
 
-@with_setup(setup, teardown)
 def test_query_with_back_reference():
     """ Insert a Record with two names. Both work in a back-ref query.
 
diff --git a/tests/test_parents.py b/tests/test_parents.py
index 19b5894546a48847d8f5146388d413f833df9217..d038350a27cb0a9bb2db79020957dc401e1b1e10 100644
--- a/tests/test_parents.py
+++ b/tests/test_parents.py
@@ -22,11 +22,11 @@ from pytest import raises, mark
 import caosdb as db
 
 
-def setup():
-    teardown()
+def setup_function(function):
+    teardown_function(function)
 
 
-def teardown():
+def teardown_function(function):
     d = db.execute_query("FIND Test*")
     if len(d) > 0:
         d.delete()
diff --git a/tests/test_permissions.py b/tests/test_permissions.py
index 3fb41c6d2731607ed3ad02e1305e2f2f2b9dab67..f35d49661a551f6ee336d85e4477233905da1515 100644
--- a/tests/test_permissions.py
+++ b/tests/test_permissions.py
@@ -45,7 +45,9 @@ easy_pw = "1234"
 
 
 def setup_module():
-    switch_to_admin_user()
+    d = db.execute_query("FIND *")
+    if len(d) > 0:
+        d.delete()
     insert_test_user()
 
 
@@ -62,6 +64,9 @@ def teardown_module():
         os.remove("test2.dat")
     except BaseException:
         pass
+    d = db.execute_query("FIND *")
+    if len(d) > 0:
+        d.delete()
 
 
 @mark.skip
@@ -146,11 +151,11 @@ def revoke_permissions_test_role():
         role=test_role, permission_rules=[])
 
 
-def teardown():
-    setup()
+def teardown_function(function):
+    setup_function(function)
 
 
-def setup():
+def setup_function(function):
     switch_to_admin_user()
     try:
         db.execute_query("FIND Test*").delete()
@@ -486,13 +491,12 @@ def test_update_role():
 
 
 def test_update_move_file():
-    upload_file = open("test.dat", "w")
-    upload_file.write("hello world\n")
-    upload_file.close()
+    with open("test.dat", "w") as upload_file:
+        upload_file.write("hello world\n")
 
     f = db.File(
         name="TestFile",
-        path="/permissiontestfiles/test.dat",
+        path="/testfiles/permissiontestfiles/test.dat",
         file="test.dat").insert()
     assert f.is_valid()
 
@@ -500,22 +504,22 @@ def test_update_move_file():
     grant_permission(f, "UPDATE:FILE:MOVE")
 
     '''SUCCESS'''
-    f.path = "/otherpermissiontestfiles/test.dat"
+    f.path = "/testfiles/otherpermissiontestfiles/test.dat"
     f.update()
 
     f2 = db.execute_query("FIND TestFile", unique=True)
-    assert_equal(f2.path, "/otherpermissiontestfiles/test.dat")
+    assert_equal(f2.path, "/testfiles/otherpermissiontestfiles/test.dat")
 
     deny_permission(f, "UPDATE:FILE:MOVE")
 
     '''FAILURE'''
-    f.path = "/againotherpermissiontestfiles/test.dat"
+    f.path = "/testfiles/againotherpermissiontestfiles/test.dat"
     with raises(db.TransactionError) as te:
         f.update()
     assert te.value.has_error(db.AuthorizationError)
 
     f2 = db.execute_query("FIND TestFile", unique=True)
-    assert f2.path == "/otherpermissiontestfiles/test.dat"
+    assert f2.path == "/testfiles/otherpermissiontestfiles/test.dat"
 
 
 def test_update_add_file():
@@ -529,7 +533,7 @@ def test_update_add_file():
     grant_permission(f, "RETRIEVE:ENTITY")
     '''FAILURE'''
 
-    f.path = "/permissiontestfiles/newtest.dat"
+    f.path = "/testfiles/permissiontestfiles/newtest.dat"
     f.file = upload_file
     with raises(db.TransactionError) as te:
         f.update()
@@ -542,13 +546,13 @@ def test_update_add_file():
     grant_permission(f, "UPDATE:FILE:ADD")
 
     f2 = db.execute_query("FIND TestFile", unique=True)
-    f2.path = "/permissiontestfiles/newtest.dat"
+    f2.path = "/testfiles/permissiontestfiles/newtest.dat"
     f2.file = upload_file
     f2.update()
     assert f2.is_valid()
 
     f2 = db.execute_query("FIND TestFile", unique=True)
-    assert_equal(f2.path, "/permissiontestfiles/newtest.dat")
+    assert_equal(f2.path, "/testfiles/permissiontestfiles/newtest.dat")
 
 
 def test_update_change_file():
@@ -563,7 +567,7 @@ def test_update_change_file():
     f = db.File(
         name="TestFile",
         file=upload_file,
-        path="permissiontestfiles/test.dat").insert()
+        path="testfiles/permissiontestfiles/test.dat").insert()
     assert f.is_valid()
     grant_permission(f, "RETRIEVE:ENTITY")
     grant_permission(f, "RETRIEVE:FILE")
@@ -925,7 +929,7 @@ def test_download_file():
     f = db.File(
         name="TestFile",
         file=upload_file,
-        path="permissiontestfiles/test.dat").insert()
+        path="testfiles/permissiontestfiles/test.dat").insert()
     assert f.is_valid()
 
     '''FAILURE'''
@@ -1110,7 +1114,6 @@ def test_use_as_parent():
         datatype=db.TEXT).add_parent(
         name="TestProperty")
 
-    deny_permission(p, "USE:AS_PARENT")
     '''Failure'''
     deny_permission(p, "USE:AS_PARENT")
     with raises(db.TransactionError) as cm:
diff --git a/tests/test_properties.py b/tests/test_properties.py
index ffedcdbd2bd38a7ee993307f52514da9116daf24..ca6aac4a5de393647f20d6143a775116f6b72bf8 100644
--- a/tests/test_properties.py
+++ b/tests/test_properties.py
@@ -32,11 +32,11 @@ def setup_module():
         d.delete()
 
 
-def setup():
+def setup_function(function):
     setup_module()
 
 
-def teardown():
+def teardown_function(function):
     setup_module()
 
 
diff --git a/tests/test_query.py b/tests/test_query.py
index 92639f2cc67002360a282089b94690e6304b4561..403aa0ad3acf7712f10701844bfa6b8841c275d2 100644
--- a/tests/test_query.py
+++ b/tests/test_query.py
@@ -43,16 +43,16 @@ def setup_module():
     assert perms == set()
 
 
-def setup():
+def setup_function(function):
     try:
-        db.execute_query("FIND Test*").delete()
+        db.execute_query("FIND *").delete()
     except Exception as e:
         print(e)
 
 
-def teardown():
+def teardown_function(function):
     db.configure_connection()
-    setup()
+    setup_function(function)
     try:
         os.remove("test.dat")
     except Exception as e:
@@ -633,9 +633,8 @@ def store_file(path, name=None, f=None):
 
 def test_stored_at_wildcards():
 
-    upload_file = open("test.dat", "w")
-    upload_file.write("hello world\n")
-    upload_file.close()
+    with open("test.dat", "w") as upload_file:
+        upload_file.write("hello world\n")
 
     file1 = store_file("test1.dat", f=upload_file)
 
diff --git a/tests/test_query_template.py b/tests/test_query_template.py
index e4c662d6d166e0b64bab6e16733b455ff3de1254..58eccf87b502587c9c7ce0c0424012006167fc03 100644
--- a/tests/test_query_template.py
+++ b/tests/test_query_template.py
@@ -78,11 +78,11 @@ def teardown_module():
         print(e)
 
 
-def setup():
+def setup_function(function):
     pass
 
 
-def teardown():
+def teardown_function(function):
     db.configure_connection()
     try:
         db.execute_query("FIND QUERYTEMPLATE Test*").delete()
diff --git a/tests/test_query_version.py b/tests/test_query_version.py
index 860bc68514327a8bbfc90777abac4974344b820f..bf6b368ff91101db7e2a4409babdfa6c8fe57c23 100644
--- a/tests/test_query_version.py
+++ b/tests/test_query_version.py
@@ -25,9 +25,8 @@ import caosdb as db
 import pytest
 from caosdb import execute_query as query
 
-db.configure_connection()
 CONTAINER = db.Container()
-NAME_PROPERTY = db.Property("name").retrieve()
+NAME_PROPERTY = db.Property("name")
 TEST_PROP_TEXT = db.Property("TestPropertyText", datatype=db.TEXT)
 TEST_PROP_DOUBLE = db.Property("TestPropertyDouble", datatype=db.DOUBLE)
 TEST_PROP_INTEGER = db.Property("TestPropertyInteger", datatype=db.INTEGER)
@@ -88,6 +87,8 @@ def teardown_module():
 
 
 def setup_module():
+    db.configure_connection()
+    NAME_PROPERTY.retrieve()
     CONTAINER.extend([TEST_RT_1, TEST_REC_1, TEST_PROP_TEXT, TEST_PROP_DOUBLE,
                       TEST_PROP_INTEGER, TEST_PROP_DATETIME, TEST_PROP_DATE,
                       TEST_REF_RT, TEST_REF_1, TEST_REF_2, TEST_REF_3,
diff --git a/tests/test_records.py b/tests/test_records.py
index 011ebef67568f7b4bd6ff0097e601cef414c5fdb..182375ba2495539025b47cb604f1acaed07adade 100644
--- a/tests/test_records.py
+++ b/tests/test_records.py
@@ -30,7 +30,7 @@ from caosdb.exceptions import CaosDBException
 import caosdb
 
 
-def teardown():
+def teardown_function(function):
     try:
         caosdb.execute_query("FIND Test*").delete()
     except Exception as e:
diff --git a/tests/test_recursive_parents.py b/tests/test_recursive_parents.py
index 1efd9390d9a01a417f91bca1cce7f0f76c154e4b..76178cee37db9ebeb2d249837bdfde80baa58141 100644
--- a/tests/test_recursive_parents.py
+++ b/tests/test_recursive_parents.py
@@ -38,12 +38,12 @@ def setup_module():
         raise_exception_on_error=False)
 
 
-def setup():
+def setup_function(function):
     """No further setup required"""
     setup_module()
 
 
-def teardown():
+def teardown_function(function):
     """Delete again"""
     setup_module()
 
diff --git a/tests/test_server_side_scripting.py b/tests/test_server_side_scripting.py
index 1c032523d1efee8c4c930235f79e8fd81259cc2c..5801f98a7b634c2c391d531be42f3c4878cc1d2c 100644
--- a/tests/test_server_side_scripting.py
+++ b/tests/test_server_side_scripting.py
@@ -70,11 +70,11 @@ def clean_database():
         d.delete()
 
 
-def setup():
+def setup_function(function):
     clean_database()
 
 
-def teardown():
+def teardown_function(function):
     admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS",
                               _ORIGINAL_SERVER_SCRIPTING_BIN_DIR)
     clean_database()
@@ -227,7 +227,8 @@ def test_diagnostics_basic():
     print(etree.tostring(xml))
 
     assert response.status == 200  # ok
-    assert response.getheader("Content-Type") == 'text/xml; charset=UTF-8'
+    assert "text/xml" in response.getheader("Content-Type").lower()
+    assert "charset=utf-8" in response.getheader("Content-Type").lower()
 
     diagnostics = xml.xpath("/Response/script/stdout")[0].text
     assert diagnostics is not None
@@ -266,7 +267,8 @@ def test_diagnostics_with_file_upload():
     response = get_connection().insert(
         ["scripting"], body=body, headers=headers)
     assert response.status == 200  # ok
-    assert response.getheader("Content-Type") == 'text/xml; charset=UTF-8'
+    assert "text/xml" in response.getheader("Content-Type").lower()
+    assert "charset=utf-8" in response.getheader("Content-Type").lower()
 
     xml = etree.parse(response)
     print(etree.tostring(xml))
@@ -316,7 +318,8 @@ def test_call_as_anonymous_with_administration_role():
     xml = etree.parse(response)
 
     assert response.getheader("Set-Cookie") is None  # no auth token returned
-    assert response.getheader("Content-Type") == 'text/xml; charset=UTF-8'
+    assert "text/xml" in response.getheader("Content-Type").lower()
+    assert "charset=utf-8" in response.getheader("Content-Type").lower()
 
     assert response.status == 200  # ok
     assert xml.xpath("/Response/script/@code")[0] == "0"
@@ -390,7 +393,8 @@ def test_anonymous_script_calling_success():
                        body=urlencode(form))
     assert response.status == 200  # ok
     assert response.getheader("Set-Cookie") is None  # no auth token returned
-    assert response.getheader("Content-Type") == 'text/xml; charset=UTF-8'
+    assert "text/xml" in response.getheader("Content-Type").lower()
+    assert "charset=utf-8" in response.getheader("Content-Type").lower()
 
     body = response.read()
     xml = etree.fromstring(body)
diff --git a/tests/test_state.py b/tests/test_state.py
index 1bc8a49c823eedd3479e52f9841bd6ac578346a6..0b2c510d5c78609e9f9797336687446a7b20e2d6 100644
--- a/tests/test_state.py
+++ b/tests/test_state.py
@@ -1,3 +1,25 @@
+# encoding: utf-8
+#
+# This file is a part of the CaosDB Project.
+#
+# Copyright (C) 2020-2022 IndiScale GmbH <info@indiscale.com>
+# Copyright (C) 2020-2022 Timm Fitschen <t.fitschen@indiscale.com>
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+# ** end header
+#
 import pytest
 import caosdb as db
 from caosdb import administration as admin
@@ -49,6 +71,8 @@ def setup_users():
                 "Grant", "STATE:TRANSITION:Transition4"),
             db.administration.PermissionRule(
                 "Grant", "STATE:TRANSITION:EditTransition"),
+            db.administration.PermissionRule(
+                "Grant", "STATE:TRANSITION:StartReviewTransition"),
         ])
     db.administration._set_permissions(
         role="team-leader", permission_rules=[
@@ -109,6 +133,7 @@ def setup_module():
             "ACL": None})
     state_acl = db.ACL()
     state_acl.grant(role="role1", permission="UPDATE:DESCRIPTION")
+    state_acl.deny(role="anonymous", permission="RETRIEVE:ENTITY")
     state_acl = db.State.create_state_acl(state_acl)
     st1.acl = state_acl.combine(st1.acl)
     st1.update_acl()
@@ -142,16 +167,18 @@ def setup_module():
         "State1").insert()
 
 
-def teardown():
+def teardown_function(function):
     switch_to_admin_user()
+    # deactivate anonymous user
+    db.administration.set_server_property("AUTH_OPTIONAL", "FALSE")
     d = db.execute_query("FIND TestRT")
     if len(d) > 0:
         d.delete(flags={"forceFinalState": "true"})
 
 
-def setup():
+def setup_function(function):
     admin.set_server_property("EXT_ENTITY_STATE", "ENABLED")
-    teardown()
+    teardown_function(function)
     db.RecordType("TestRT").insert()
 
 
@@ -478,10 +505,16 @@ def test_transfer_state_acl():
     rec.state = db.State(model="Model1", name="State1")
     insert_rec = rec.insert(flags={"ACL": None})
 
-    state_acl = db.ACL().combine(db.get_global_acl())
+    state_acl = db.ACL()
     state_acl.grant(role="role1", permission="UPDATE:DESCRIPTION")
+    state_acl.deny(role="anonymous", permission="RETRIEVE:ENTITY")
+    state_acl = state_acl.combine(db.get_global_acl())
 
     # the acl has been transfered from the state record
+    assert insert_rec.acl.get_permissions_for_role("role1") == {
+        "UPDATE:DESCRIPTION"}
+    assert "RETRIEVE:ENTITY" not in insert_rec.acl.get_permissions_for_role(
+        "anonymous")
     assert insert_rec.acl == state_acl
 
 
@@ -624,11 +657,11 @@ def test_full_edit_review_publish_cycle():
     rec.update()
 
     # start review
-    switch_to_test_user("team-leader")
     rec.state = db.State(model="EditReviewPublish", name="ReviewState")
     rec.update()
 
     # as team-leader
+    switch_to_test_user("team-leader")
     rec.get_property("TestProperty").value = next(val)
     rec.update()
 
@@ -804,3 +837,29 @@ def test_transitions_included_after_empty_update():
                                               db.Transition(name="Transition4",
                                                             from_state="State2",
                                                             to_state="State2")}
+
+
+def test_missing_retrieve_permission():
+    """When the retrieve permission is missing, the state must not be leaked."""
+    # @review Florian Spreckelsen 2022-03-22
+    rec = db.Record()
+    rec.description = "old description"
+    rec.add_parent("TestRT")
+    rec.state = db.State(model="Model1", name="State1")
+    rec.insert(flags={"ACL": None})
+    print(rec)
+
+    # switch to anonymous
+    db.administration.set_server_property("AUTH_OPTIONAL", "TRUE")
+    db.configure_connection(password_method="unauthenticated")
+    assert db.Info().user_info.roles == ["anonymous"]
+
+    rec2 = db.Record(id=rec.id)
+    with pytest.raises(db.TransactionError) as te:
+        rec2.retrieve()
+    assert te.value.has_error(db.AuthorizationError)
+
+    rec2 = db.Record(id=rec.id)
+    rec2.retrieve(raise_exception_on_error=False)
+    assert len(rec2.get_errors()) > 0
+    assert rec2.state is None
diff --git a/tests/test_tickets.py b/tests/test_tickets.py
index bcffcd31a05b1fcce33af415f9e27bcc11579b6b..fb41af36e86131fa913d83faf391ca02c90cd82a 100644
--- a/tests/test_tickets.py
+++ b/tests/test_tickets.py
@@ -32,14 +32,14 @@ import pytest
 from tests import test_misc
 
 
-def setup():
+def setup_function(function):
     d = db.execute_query("FIND Test*")
     if len(d) > 0:
         d.delete()
 
 
-def teardown():
-    setup()
+def teardown_function(function):
+    setup_function(function)
 
 
 def test_ticket_103a():
diff --git a/tests/test_tickets_300.py b/tests/test_tickets_300.py
index 43fbd97f0fc3ea67e23736657d9cac07886fff35..cf34637d82d3a8dfb00751d26f3b7cfc40351d60 100644
--- a/tests/test_tickets_300.py
+++ b/tests/test_tickets_300.py
@@ -45,11 +45,11 @@ def teardown_module():
     _delete_test_entities()
 
 
-def setup():
+def setup_function(function):
     setup_module()
 
 
-def teardown():
+def teardown_function(function):
     teardown_module()
 
 
diff --git a/tests/test_update.py b/tests/test_update.py
index f783ff1339289679e1866e7ae8130560d1c76500..becaf5bb4469650f54c481977b1e05d2c667812f 100644
--- a/tests/test_update.py
+++ b/tests/test_update.py
@@ -34,14 +34,14 @@ from caosdb.common.utils import xml2str
 from caosdb.common.models import raise_errors
 
 
-def setup():
+def setup_function(function):
     d = db.execute_query("FIND Entity WITH ID > 99")
     if len(d) > 0:
         d.delete()
 
 
-def teardown():
-    setup()
+def teardown_function(function):
+    setup_function(function)
 
 
 def test_property_no_id():
diff --git a/tests/test_version.py b/tests/test_version.py
index 2b8aafa882832a419fe1b796a703b0b31cb3b766..4abf10a19f8e4c059334d5e247b0aae59738f395 100644
--- a/tests/test_version.py
+++ b/tests/test_version.py
@@ -25,14 +25,14 @@ from pytest import mark, raises
 import caosdb as c
 
 
-def setup():
+def setup_function(function):
     d = c.execute_query("FIND Test*")
     if len(d) > 0:
         d.delete()
 
 
-def teardown():
-    setup()
+def teardown_function(function):
+    setup_function(function)
 
 
 def test_version_object():
diff --git a/tox.ini b/tox.ini
index 26c5d1594c48fe755a355a3aee711fd6608c6f97..03ab50d132a82e6f7ee4b26cb55156e211f24b01 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,10 @@
 [tox]
-envlist=py36, py37, py38, py39
+envlist=py36, py37, py38, py39, py310
 skip_missing_interpreters = true
+
+[pycodestyle]
+max_line_length = 100
+
 [testenv]
 setenv = PASSWORD_STORE_DIR = {env:HOME}/.password-store
 passenv = PYCAOSDBINI