diff --git a/ldap_server_entries_add.ldif b/tests/openldap_ldifs/ldap_server_entries_add.ldif
similarity index 100%
rename from ldap_server_entries_add.ldif
rename to tests/openldap_ldifs/ldap_server_entries_add.ldif
diff --git a/ldap_server_entries_cleanup.ldif b/tests/openldap_ldifs/ldap_server_entries_cleanup.ldif
similarity index 100%
rename from ldap_server_entries_cleanup.ldif
rename to tests/openldap_ldifs/ldap_server_entries_cleanup.ldif
diff --git a/ldap_server_entries_modify.ldif b/tests/openldap_ldifs/ldap_server_entries_modify.ldif
similarity index 100%
rename from ldap_server_entries_modify.ldif
rename to tests/openldap_ldifs/ldap_server_entries_modify.ldif
diff --git a/ldap_server_entries.json b/tests/openldap_mock/ldap_server_entries.json
similarity index 100%
rename from ldap_server_entries.json
rename to tests/openldap_mock/ldap_server_entries.json
diff --git a/ldap_server_info.json b/tests/openldap_mock/ldap_server_info.json
similarity index 100%
rename from ldap_server_info.json
rename to tests/openldap_mock/ldap_server_info.json
diff --git a/ldap_server_schema.json b/tests/openldap_mock/ldap_server_schema.json
similarity index 100%
rename from ldap_server_schema.json
rename to tests/openldap_mock/ldap_server_schema.json
diff --git a/tests/test_invite.py b/tests/test_invite.py
index a6b770aa9e88abf0eaefa857f2d5d628b47d7cef..7c6bf2fb762c447d38d8fc5f0088ceca51c470df 100644
--- a/tests/test_invite.py
+++ b/tests/test_invite.py
@@ -47,20 +47,20 @@ class TestInviteModel(UffdTestCase):
 		invite.creator_dn = 'uid=doesnotexist,ou=users,dc=example,dc=com'
 		self.assertFalse(invite.permitted)
 		self.assertFalse(invite.active)
-		invite.creator_dn = 'uid=testadmin,ou=users,dc=example,dc=com'
+		invite.creator_dn = self.test_data.get('admin').get('dn')
 		self.assertTrue(invite.permitted)
 		self.assertTrue(invite.active)
-		invite.creator_dn = 'uid=testuser,ou=users,dc=example,dc=com'
+		invite.creator_dn = self.test_data.get('user').get('dn')
 		self.assertFalse(invite.permitted)
 		self.assertFalse(invite.active)
-		role.moderator_group_dn = 'cn=uffd_access,ou=groups,dc=example,dc=com'
+		role.moderator_group_dn = self.test_data.get('group_uffd_access').get('dn')
 		current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access'
 		self.assertTrue(invite.permitted)
 		self.assertTrue(invite.active)
 		role.moderator_group_dn = None
 		self.assertFalse(invite.permitted)
 		self.assertFalse(invite.active)
-		role.moderator_group_dn = 'cn=uffd_access,ou=groups,dc=example,dc=com'
+		role.moderator_group_dn = self.test_data.get('group_uffd_access').get('dn')
 		current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_admin'
 		self.assertFalse(invite.permitted)
 		self.assertFalse(invite.active)
@@ -100,13 +100,13 @@ class TestInviteModel(UffdTestCase):
 
 class TestInviteGrantModel(UffdTestCase):
 	def test_success(self):
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		group0 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')
+		user = self.get_user()
+		group0 = self.get_access_group()
 		role0 = Role(name='baserole', groups={group0: RoleGroup(group=group0)})
 		db.session.add(role0)
 		user.roles.add(role0)
 		user.update_groups()
-		group1 = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')
+		group1 = self.get_admin_group()
 		role1 = Role(name='testrole1', groups={group1: RoleGroup(group=group1)})
 		db.session.add(role1)
 		role2 = Role(name='testrole2')
@@ -130,16 +130,16 @@ class TestInviteGrantModel(UffdTestCase):
 		db.session.commit()
 		ldap.session.commit()
 		db_flush()
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user = self.get_user()
 		self.assertIn('baserole', [role.name for role in user.roles_effective])
 		self.assertIn('testrole1', [role.name for role in user.roles])
 		self.assertIn('testrole2', [role.name for role in user.roles])
-		self.assertIn('cn=uffd_access,ou=groups,dc=example,dc=com', [group.dn for group in user.groups])
-		self.assertIn('cn=uffd_admin,ou=groups,dc=example,dc=com', [group.dn for group in user.groups])
+		self.assertIn(self.test_data.get('group_uffd_access').get('dn'), [group.dn for group in user.groups])
+		self.assertIn(self.test_data.get('group_uffd_admin').get('dn'), [group.dn for group in user.groups])
 
 	def test_inactive(self):
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		group = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')
+		user = self.get_user()
+		group = self.get_admin_group()
 		role = Role(name='testrole1', groups={group: RoleGroup(group=group)})
 		db.session.add(role)
 		invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), roles=[role], single_use=True, used=True)
@@ -152,7 +152,7 @@ class TestInviteGrantModel(UffdTestCase):
 		self.assertNotIn(group, user.groups)
 
 	def test_no_roles(self):
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user = self.get_user()
 		invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60))
 		self.assertTrue(invite.active)
 		grant = InviteGrant(invite=invite, user=user)
@@ -161,7 +161,7 @@ class TestInviteGrantModel(UffdTestCase):
 		self.assertIsInstance(msg, str)
 
 	def test_no_new_roles(self):
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user = self.get_user()
 		role = Role(name='testrole1')
 		db.session.add(role)
 		user.roles.add(role)
@@ -175,17 +175,17 @@ class TestInviteGrantModel(UffdTestCase):
 class TestInviteSignupModel(UffdTestCase):
 	def create_base_roles(self):
 		baserole = Role(name='base', is_default=True)
-		baserole.groups[Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')] = RoleGroup()
-		baserole.groups[Group.query.get('cn=users,ou=groups,dc=example,dc=com')] = RoleGroup()
+		baserole.groups[self.get_access_group()] = RoleGroup()
+		baserole.groups[self.get_users_group()] = RoleGroup()
 		db.session.add(baserole)
 		db.session.commit()
 
 	def test_success(self):
 		self.create_base_roles()
 		base_role = Role.query.filter_by(name='base').one()
-		base_group1 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')
-		base_group2 = Group.query.get('cn=users,ou=groups,dc=example,dc=com')
-		group = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')
+		base_group1 = self.get_access_group()
+		base_group2 = self.get_users_group()
+		group = self.get_admin_group()
 		role1 = Role(name='testrole1', groups={group: RoleGroup(group=group)})
 		db.session.add(role1)
 		role2 = Role(name='testrole2')
@@ -217,8 +217,8 @@ class TestInviteSignupModel(UffdTestCase):
 	def test_success_no_roles(self):
 		self.create_base_roles()
 		base_role = Role.query.filter_by(name='base').one()
-		base_group1 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')
-		base_group2 = Group.query.get('cn=users,ou=groups,dc=example,dc=com')
+		base_group1 = self.get_access_group()
+		base_group2 = self.get_users_group()
 		invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True)
 		signup = InviteSignup(invite=invite, loginname='newuser', displayname='New User', mail='test@example.com', password='notsecret')
 		self.assertFalse(invite.used)
@@ -285,19 +285,11 @@ class TestInviteAdminViews(UffdTestCase):
 		self.app.config['SELF_SIGNUP'] = False
 		self.app.last_mail = None
 
-	def login_admin(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testadmin', 'password': 'adminpassword'}, follow_redirects=True)
-
-	def login_user(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
-
 	def test_index(self):
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
 		valid_until_expired = datetime.datetime.now() - datetime.timedelta(seconds=60)
-		user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		user1 = self.get_user()
+		user2 = self.get_admin()
 		role1 = Role(name='testrole1')
 		db.session.add(role1)
 		role2 = Role(name='testrole2')
@@ -314,13 +306,13 @@ class TestInviteAdminViews(UffdTestCase):
 		db.session.add(Invite(valid_until=valid_until, allow_signup=True, roles=[role1], grants=[InviteGrant(user=user2)]))
 		db.session.add(Invite(valid_until=valid_until, allow_signup=False, roles=[role1, role2]))
 		db.session.commit()
-		self.login_admin()
+		self.login_as('admin')
 		r = self.client.get(path=url_for('invite.index'), follow_redirects=True)
 		dump('invite_index', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_index_empty(self):
-		self.login_admin()
+		self.login_as('admin')
 		r = self.client.get(path=url_for('invite.index'), follow_redirects=True)
 		dump('invite_index_empty', r)
 		self.assertEqual(r.status_code, 200)
@@ -331,7 +323,7 @@ class TestInviteAdminViews(UffdTestCase):
 		self.assertEqual(r.status_code, 200)
 
 	def test_index_noaccess(self):
-		self.login_user()
+		self.login_as('user')
 		r = self.client.get(path=url_for('invite.index'), follow_redirects=True)
 		dump('invite_index_noaccess', r)
 		self.assertEqual(r.status_code, 200)
@@ -340,9 +332,9 @@ class TestInviteAdminViews(UffdTestCase):
 	def test_index_signupperm(self):
 		current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access'
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
-		invite1 = Invite(valid_until=valid_until, allow_signup=True, creator_dn='uid=testadmin,ou=users,dc=example,dc=com')
+		invite1 = Invite(valid_until=valid_until, allow_signup=True, creator_dn=self.test_data.get('admin').get('dn'))
 		db.session.add(invite1)
-		invite2 = Invite(valid_until=valid_until, allow_signup=True, creator_dn='uid=testuser,ou=users,dc=example,dc=com')
+		invite2 = Invite(valid_until=valid_until, allow_signup=True, creator_dn=self.test_data.get('user').get('dn'))
 		db.session.add(invite2)
 		invite3 = Invite(valid_until=valid_until, allow_signup=True)
 		db.session.add(invite3)
@@ -350,7 +342,7 @@ class TestInviteAdminViews(UffdTestCase):
 		token1 = invite1.short_token
 		token2 = invite2.short_token
 		token3 = invite3.short_token
-		self.login_user()
+		self.login_as('user')
 		r = self.client.get(path=url_for('invite.index'), follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
 		self.assertNotIn('Access denied'.encode(), r.data)
@@ -361,13 +353,13 @@ class TestInviteAdminViews(UffdTestCase):
 	def test_index_rolemod(self):
 		role1 = Role(name='testrole1')
 		db.session.add(role1)
-		role2 = Role(name='testrole2', moderator_group_dn='cn=uffd_access,ou=groups,dc=example,dc=com')
+		role2 = Role(name='testrole2', moderator_group_dn=self.test_data.get('group_uffd_access').get('dn'))
 		db.session.add(role2)
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
 		db.session.add(Invite(valid_until=valid_until, roles=[role1]))
 		db.session.add(Invite(valid_until=valid_until, roles=[role2]))
 		db.session.commit()
-		self.login_user()
+		self.login_as('user')
 		r = self.client.get(path=url_for('invite.index'), follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
 		self.assertNotIn('Access denied'.encode(), r.data)
@@ -375,7 +367,7 @@ class TestInviteAdminViews(UffdTestCase):
 		self.assertIn('testrole2'.encode(), r.data)
 
 	def test_new(self):
-		self.login_admin()
+		self.login_as('admin')
 		role = Role(name='testrole1')
 		db.session.add(role)
 		db.session.commit()
@@ -398,7 +390,7 @@ class TestInviteAdminViews(UffdTestCase):
 
 	def test_new_noperm(self):
 		current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access'
-		self.login_user()
+		self.login_as('user')
 		role = Role(name='testrole1')
 		db.session.add(role)
 		db.session.commit()
@@ -412,7 +404,7 @@ class TestInviteAdminViews(UffdTestCase):
 
 	def test_new_empty(self):
 		current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access'
-		self.login_user()
+		self.login_as('user')
 		valid_until = (datetime.datetime.now() + datetime.timedelta(seconds=60)).isoformat()
 		r = self.client.post(path=url_for('invite.new_submit'),
 			data={'single-use': '1', 'valid-until': valid_until,
@@ -421,7 +413,7 @@ class TestInviteAdminViews(UffdTestCase):
 		self.assertIsNone(Invite.query.first())
 
 	def test_disable(self):
-		self.login_admin()
+		self.login_as('admin')
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
 		invite = Invite(valid_until=valid_until)
 		db.session.add(invite)
@@ -434,9 +426,9 @@ class TestInviteAdminViews(UffdTestCase):
 
 	def test_disable_own(self):
 		current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access'
-		self.login_user()
+		self.login_as('user')
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
-		invite = Invite(valid_until=valid_until, creator_dn='uid=testuser,ou=users,dc=example,dc=com')
+		invite = Invite(valid_until=valid_until, creator_dn=self.test_data.get('user').get('dn'))
 		db.session.add(invite)
 		db.session.commit()
 		id = invite.id
@@ -446,11 +438,11 @@ class TestInviteAdminViews(UffdTestCase):
 		self.assertTrue(Invite.query.get(id).disabled)
 
 	def test_disable_rolemod(self):
-		self.login_user()
+		self.login_as('user')
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
-		role = Role(name='testrole', moderator_group_dn='cn=uffd_access,ou=groups,dc=example,dc=com')
+		role = Role(name='testrole', moderator_group_dn=self.test_data.get('group_uffd_access').get('dn'))
 		db.session.add(role)
-		invite = Invite(valid_until=valid_until, creator_dn='uid=testadmin,ou=users,dc=example,dc=com', roles=[role])
+		invite = Invite(valid_until=valid_until, creator_dn=self.test_data.get('admin').get('dn'), roles=[role])
 		db.session.add(invite)
 		db.session.commit()
 		id = invite.id
@@ -459,12 +451,12 @@ class TestInviteAdminViews(UffdTestCase):
 		self.assertTrue(Invite.query.get(id).disabled)
 
 	def test_disable_noperm(self):
-		self.login_user()
+		self.login_as('user')
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
-		db.session.add(Role(name='testrole1', moderator_group_dn='cn=uffd_access,ou=groups,dc=example,dc=com'))
-		role = Role(name='testrole2', moderator_group_dn='cn=uffd_admin,ou=groups,dc=example,dc=com')
+		db.session.add(Role(name='testrole1', moderator_group_dn=self.test_data.get('group_uffd_access').get('dn')))
+		role = Role(name='testrole2', moderator_group_dn=self.test_data.get('group_uffd_admin').get('dn'))
 		db.session.add(role)
-		invite = Invite(valid_until=valid_until, creator_dn='uid=testadmin,ou=users,dc=example,dc=com', roles=[role])
+		invite = Invite(valid_until=valid_until, creator_dn=self.test_data.get('admin').get('dn'), roles=[role])
 		db.session.add(invite)
 		db.session.commit()
 		id = invite.id
@@ -473,7 +465,7 @@ class TestInviteAdminViews(UffdTestCase):
 		self.assertTrue(Invite.query.get(id).active)
 
 	def test_reset_disabled(self):
-		self.login_admin()
+		self.login_as('admin')
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
 		invite = Invite(valid_until=valid_until, disabled=True)
 		db.session.add(invite)
@@ -485,7 +477,7 @@ class TestInviteAdminViews(UffdTestCase):
 		self.assertTrue(Invite.query.get(id).active)
 
 	def test_reset_voided(self):
-		self.login_admin()
+		self.login_as('admin')
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
 		invite = Invite(valid_until=valid_until, single_use=True, used=True)
 		db.session.add(invite)
@@ -498,9 +490,9 @@ class TestInviteAdminViews(UffdTestCase):
 
 	def test_reset_own(self):
 		current_app.config['ACL_SIGNUP_GROUP'] = 'uffd_access'
-		self.login_user()
+		self.login_as('user')
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
-		invite = Invite(valid_until=valid_until, disabled=True, creator_dn='uid=testuser,ou=users,dc=example,dc=com')
+		invite = Invite(valid_until=valid_until, disabled=True, creator_dn=self.test_data.get('user').get('dn'))
 		db.session.add(invite)
 		db.session.commit()
 		id = invite.id
@@ -510,11 +502,11 @@ class TestInviteAdminViews(UffdTestCase):
 		self.assertTrue(Invite.query.get(id).active)
 
 	def test_reset_foreign(self):
-		self.login_user()
+		self.login_as('user')
 		valid_until = datetime.datetime.now() + datetime.timedelta(seconds=60)
-		role = Role(name='testrole', moderator_group_dn='cn=uffd_access,ou=groups,dc=example,dc=com')
+		role = Role(name='testrole', moderator_group_dn=self.test_data.get('group_uffd_access').get('dn'))
 		db.session.add(role)
-		invite = Invite(valid_until=valid_until, disabled=True, creator_dn='uid=testadmin,ou=users,dc=example,dc=com', roles=[role])
+		invite = Invite(valid_until=valid_until, disabled=True, creator_dn=self.test_data.get('admin').get('dn'), roles=[role])
 		db.session.add(invite)
 		db.session.commit()
 		id = invite.id
@@ -527,10 +519,6 @@ class TestInviteUseViews(UffdTestCase):
 		self.app.config['SELF_SIGNUP'] = False
 		self.app.last_mail = None
 
-	def login_user(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
-
 	def test_use(self):
 		invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True, roles=[Role(name='testrole1'), Role(name='testrole2')])
 		db.session.add(invite)
@@ -541,7 +529,7 @@ class TestInviteUseViews(UffdTestCase):
 		self.assertEqual(r.status_code, 200)
 
 	def test_use_loggedin(self):
-		self.login_user()
+		self.login_as('user')
 		invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), allow_signup=True, roles=[Role(name='testrole1'), Role(name='testrole2')])
 		db.session.add(invite)
 		db.session.commit()
@@ -562,13 +550,13 @@ class TestInviteUseViews(UffdTestCase):
 	# TODO: test cases for {logged in, not logged in} x (signup-only, grant-only, both, none?}
 
 	def test_grant(self):
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		group0 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')
+		user = self.get_user()
+		group0 = self.get_access_group()
 		role0 = Role(name='baserole', groups={group0: RoleGroup(group=group0)})
 		db.session.add(role0)
 		user.roles.add(role0)
 		user.update_groups()
-		group1 = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')
+		group1 = self.get_admin_group()
 		role1 = Role(name='testrole1', groups={group1: RoleGroup(group=group1)})
 		db.session.add(role1)
 		role2 = Role(name='testrole2')
@@ -584,26 +572,26 @@ class TestInviteUseViews(UffdTestCase):
 		self.assertIn(group0, user.groups)
 		self.assertNotIn(group1, user.groups)
 		self.assertFalse(invite.used)
-		self.login_user()
+		self.login_as('user')
 		r = self.client.post(path=url_for('invite.grant', token=token), follow_redirects=True)
 		dump('invite_grant', r)
 		self.assertEqual(r.status_code, 200)
 		db_flush()
 		invite = Invite.query.filter_by(token=token).first()
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user = self.get_user()
 		self.assertTrue(invite.used)
 		self.assertIn('baserole', [role.name for role in user.roles])
 		self.assertIn('testrole1', [role.name for role in user.roles])
 		self.assertIn('testrole2', [role.name for role in user.roles])
-		self.assertIn('cn=uffd_access,ou=groups,dc=example,dc=com', [group.dn for group in user.groups])
-		self.assertIn('cn=uffd_admin,ou=groups,dc=example,dc=com', [group.dn for group in user.groups])
+		self.assertIn(self.test_data.get('group_uffd_access').get('dn'), [group.dn for group in user.groups])
+		self.assertIn(self.test_data.get('group_uffd_admin').get('dn'), [group.dn for group in user.groups])
 
 	def test_grant_invalid_invite(self):
 		invite = Invite(valid_until=datetime.datetime.now() + datetime.timedelta(seconds=60), disabled=True)
 		db.session.add(invite)
 		db.session.commit()
 		token = invite.token
-		self.login_user()
+		self.login_as('user')
 		r = self.client.post(path=url_for('invite.grant', token=token), follow_redirects=True)
 		dump('invite_grant_invalid_invite', r)
 		self.assertEqual(r.status_code, 200)
@@ -614,14 +602,14 @@ class TestInviteUseViews(UffdTestCase):
 		db.session.add(invite)
 		db.session.commit()
 		token = invite.token
-		self.login_user()
+		self.login_as('user')
 		r = self.client.post(path=url_for('invite.grant', token=token), follow_redirects=True)
 		dump('invite_grant_no_roles', r)
 		self.assertEqual(r.status_code, 200)
 		self.assertFalse(Invite.query.filter_by(token=token).first().used)
 
 	def test_grant_no_new_roles(self):
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user = self.get_user()
 		role = Role(name='testrole')
 		db.session.add(role)
 		user.roles.add(role)
@@ -629,7 +617,7 @@ class TestInviteUseViews(UffdTestCase):
 		db.session.add(invite)
 		db.session.commit()
 		token = invite.token
-		self.login_user()
+		self.login_as('user')
 		r = self.client.post(path=url_for('invite.grant', token=token), follow_redirects=True)
 		dump('invite_grant_no_new_roles', r)
 		self.assertEqual(r.status_code, 200)
@@ -637,10 +625,10 @@ class TestInviteUseViews(UffdTestCase):
 
 	def test_signup(self):
 		baserole = Role(name='base', is_default=True)
-		baserole.groups[Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')] = RoleGroup()
-		baserole.groups[Group.query.get('cn=users,ou=groups,dc=example,dc=com')] = RoleGroup()
+		baserole.groups[self.get_access_group()] = RoleGroup()
+		baserole.groups[self.get_users_group()] = RoleGroup()
 		db.session.add(baserole)
-		group = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')
+		group = self.get_admin_group()
 		role1 = Role(name='testrole1', groups={group: RoleGroup(group=group)})
 		db.session.add(role1)
 		role2 = Role(name='testrole2')
diff --git a/tests/test_mail.py b/tests/test_mail.py
index a5b9f88f67da1ffa8fe730bde54962b6e3ddef51..80c49e36f6ce8d3f188de1d0f1f8305190ccaf79 100644
--- a/tests/test_mail.py
+++ b/tests/test_mail.py
@@ -19,8 +19,7 @@ def get_mail():
 class TestMailViews(UffdTestCase):
 	def setUp(self):
 		super().setUp()
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testadmin', 'password': 'adminpassword'}, follow_redirects=True)
+		self.login_as('admin')
 
 	def test_index(self):
 		r = self.client.get(path=url_for('mail.index'), follow_redirects=True)
diff --git a/tests/test_mfa.py b/tests/test_mfa.py
index dc0c657cb3c7138b409474e6f3c20cd3a53d9a48..0157ad532567ffde44cc7be4a680d27f2dc65731 100644
--- a/tests/test_mfa.py
+++ b/tests/test_mfa.py
@@ -23,13 +23,7 @@ class TestMfaPrimitives(unittest.TestCase):
 		self.assertEqual(_hotp(0, b'\x04\x8fM\xcc\x7f\x82\x9c$a\x1b\xb3'), '279354')
 		self.assertEqual(_hotp(2**64-1, b'abcde'), '899292')
 
-def get_user():
-	return User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-
-def get_admin():
-	return User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
-
-def get_fido2_test_cred():
+def get_fido2_test_cred(self):
 	try:
 		from fido2.ctap2 import AttestedCredentialData
 	except ImportError:
@@ -39,15 +33,15 @@ def get_fido2_test_cred():
 
 class TestMfaMethodModels(UffdTestCase):
 	def test_common_attributes(self):
-		method = MFAMethod(user=get_user(), name='testname')
+		method = MFAMethod(user=self.get_user(), name='testname')
 		self.assertTrue(method.created <= datetime.datetime.now())
 		self.assertEqual(method.name, 'testname')
 		self.assertEqual(method.user.loginname, 'testuser')
-		method.user = get_admin()
+		method.user = self.get_admin()
 		self.assertEqual(method.user.loginname, 'testadmin')
 
 	def test_recovery_code_method(self):
-		method = RecoveryCodeMethod(user=get_user())
+		method = RecoveryCodeMethod(user=self.get_user())
 		db.session.add(method)
 		db.session.commit()
 		db.session = db.create_scoped_session() # Ensure the next query does not return the cached method object
@@ -58,10 +52,10 @@ class TestMfaMethodModels(UffdTestCase):
 		self.assertTrue(_method.verify(method.code))
 
 	def test_totp_method_attributes(self):
-		method = TOTPMethod(user=get_user(), name='testname')
+		method = TOTPMethod(user=self.get_user(), name='testname')
 		self.assertEqual(method.name, 'testname')
 		# Restore method with key parameter
-		_method = TOTPMethod(user=get_user(), key=method.key, name='testname')
+		_method = TOTPMethod(user=self.get_user(), key=method.key, name='testname')
 		self.assertEqual(_method.name, 'testname')
 		self.assertEqual(method.raw_key, _method.raw_key)
 		self.assertEqual(method.issuer, _method.issuer)
@@ -79,7 +73,7 @@ class TestMfaMethodModels(UffdTestCase):
 		self.assertEqual(method.key_uri, _method.key_uri)
 
 	def test_totp_method_verify(self):
-		method = TOTPMethod(user=get_user())
+		method = TOTPMethod(user=self.get_user())
 		counter = int(time.time()/30)
 		self.assertFalse(method.verify(''))
 		self.assertFalse(method.verify(_hotp(counter-2, method.raw_key)))
@@ -87,8 +81,8 @@ class TestMfaMethodModels(UffdTestCase):
 		self.assertFalse(method.verify(_hotp(counter+2, method.raw_key)))
 
 	def test_webauthn_method(self):
-		data = get_fido2_test_cred()
-		method = WebauthnMethod(user=get_user(), cred=data, name='testname')
+		data = get_fido2_test_cred(self)
+		method = WebauthnMethod(user=self.get_user(), cred=data, name='testname')
 		self.assertEqual(method.name, 'testname')
 		db.session.add(method)
 		db.session.commit()
@@ -103,45 +97,41 @@ class TestMfaMethodModels(UffdTestCase):
 class TestMfaViews(UffdTestCase):
 	def setUp(self):
 		super().setUp()
-		db.session.add(RecoveryCodeMethod(user=get_admin()))
-		db.session.add(TOTPMethod(user=get_admin(), name='Admin Phone'))
+		db.session.add(RecoveryCodeMethod(user=self.get_admin()))
+		db.session.add(TOTPMethod(user=self.get_admin(), name='Admin Phone'))
 		# We don't want to skip all tests only because fido2 is not installed!
-		#db.session.add(WebauthnMethod(user=get_admin(), cred=get_fido2_test_cred(), name='Admin FIDO2 dongle'))
+		#db.session.add(WebauthnMethod(user=get_testadmin(), cred=get_fido2_test_cred(self), name='Admin FIDO2 dongle'))
 		db.session.commit()
 
-	def login(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
-
 	def add_recovery_codes(self, count=10):
-		user = get_user()
+		user = self.get_user()
 		for _ in range(count):
 			db.session.add(RecoveryCodeMethod(user=user))
 		db.session.commit()
 
 	def add_totp(self):
-		db.session.add(TOTPMethod(user=get_user(), name='My phone'))
+		db.session.add(TOTPMethod(user=self.get_user(), name='My phone'))
 		db.session.commit()
 
 	def add_webauthn(self):
-		db.session.add(WebauthnMethod(user=get_user(), cred=get_fido2_test_cred(), name='My FIDO2 dongle'))
+		db.session.add(WebauthnMethod(user=self.get_user(), cred=get_fido2_test_cred(self), name='My FIDO2 dongle'))
 		db.session.commit()
 
 	def test_setup_disabled(self):
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('mfa.setup'), follow_redirects=True)
 		dump('mfa_setup_disabled', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_setup_recovery_codes(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
 		r = self.client.get(path=url_for('mfa.setup'), follow_redirects=True)
 		dump('mfa_setup_only_recovery_codes', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_setup_enabled(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
 		self.add_totp()
 		self.add_webauthn()
@@ -150,7 +140,7 @@ class TestMfaViews(UffdTestCase):
 		self.assertEqual(r.status_code, 200)
 
 	def test_setup_few_recovery_codes(self):
-		self.login()
+		self.login_as('user')
 		self.add_totp()
 		self.add_recovery_codes(1)
 		r = self.client.get(path=url_for('mfa.setup'), follow_redirects=True)
@@ -158,17 +148,17 @@ class TestMfaViews(UffdTestCase):
 		self.assertEqual(r.status_code, 200)
 
 	def test_setup_no_recovery_codes(self):
-		self.login()
+		self.login_as('user')
 		self.add_totp()
 		r = self.client.get(path=url_for('mfa.setup'), follow_redirects=True)
 		dump('mfa_setup_no_recovery_codes', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_disable(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
 		self.add_totp()
-		admin_methods = len(MFAMethod.query.filter_by(dn=get_admin().dn).all())
+		admin_methods = len(MFAMethod.query.filter_by(dn=self.get_admin().dn).all())
 		r = self.client.get(path=url_for('mfa.disable'), follow_redirects=True)
 		dump('mfa_disable', r)
 		self.assertEqual(r.status_code, 200)
@@ -176,12 +166,12 @@ class TestMfaViews(UffdTestCase):
 		dump('mfa_disable_submit', r)
 		self.assertEqual(r.status_code, 200)
 		self.assertEqual(len(MFAMethod.query.filter_by(dn=request.user.dn).all()), 0)
-		self.assertEqual(len(MFAMethod.query.filter_by(dn=get_admin().dn).all()), admin_methods)
+		self.assertEqual(len(MFAMethod.query.filter_by(dn=self.get_admin().dn).all()), admin_methods)
 
 	def test_disable_recovery_only(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
-		admin_methods = len(MFAMethod.query.filter_by(dn=get_admin().dn).all())
+		admin_methods = len(MFAMethod.query.filter_by(dn=self.get_admin().dn).all())
 		self.assertNotEqual(len(MFAMethod.query.filter_by(dn=request.user.dn).all()), 0)
 		r = self.client.get(path=url_for('mfa.disable'), follow_redirects=True)
 		dump('mfa_disable_recovery_only', r)
@@ -190,27 +180,26 @@ class TestMfaViews(UffdTestCase):
 		dump('mfa_disable_recovery_only_submit', r)
 		self.assertEqual(r.status_code, 200)
 		self.assertEqual(len(MFAMethod.query.filter_by(dn=request.user.dn).all()), 0)
-		self.assertEqual(len(MFAMethod.query.filter_by(dn=get_admin().dn).all()), admin_methods)
+		self.assertEqual(len(MFAMethod.query.filter_by(dn=self.get_admin().dn).all()), admin_methods)
 
 	def test_admin_disable(self):
-		for method in MFAMethod.query.filter_by(dn=get_admin().dn).all():
+		for method in MFAMethod.query.filter_by(dn=self.get_admin().dn).all():
 			if not isinstance(method, RecoveryCodeMethod):
 				db.session.delete(method)
 		db.session.commit()
 		self.add_recovery_codes()
 		self.add_totp()
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testadmin', 'password': 'adminpassword'}, follow_redirects=True)
+		self.login_as('admin')
 		self.assertIsNotNone(request.user)
-		admin_methods = len(MFAMethod.query.filter_by(dn=get_admin().dn).all())
-		r = self.client.get(path=url_for('mfa.admin_disable', uid=get_user().uid), follow_redirects=True)
+		admin_methods = len(MFAMethod.query.filter_by(dn=self.get_admin().dn).all())
+		r = self.client.get(path=url_for('mfa.admin_disable', uid=self.get_user().uid), follow_redirects=True)
 		dump('mfa_admin_disable', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertEqual(len(MFAMethod.query.filter_by(dn=get_user().dn).all()), 0)
-		self.assertEqual(len(MFAMethod.query.filter_by(dn=get_admin().dn).all()), admin_methods)
+		self.assertEqual(len(MFAMethod.query.filter_by(dn=self.get_user().dn).all()), 0)
+		self.assertEqual(len(MFAMethod.query.filter_by(dn=self.get_admin().dn).all()), admin_methods)
 
 	def test_setup_recovery(self):
-		self.login()
+		self.login_as('user')
 		self.assertEqual(len(RecoveryCodeMethod.query.filter_by(dn=request.user.dn).all()), 0)
 		r = self.client.post(path=url_for('mfa.setup_recovery'), follow_redirects=True)
 		dump('mfa_setup_recovery', r)
@@ -224,7 +213,7 @@ class TestMfaViews(UffdTestCase):
 		self.assertNotEqual(len(methods), 0)
 
 	def test_setup_totp(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
 		r = self.client.get(path=url_for('mfa.setup_totp', name='My TOTP Authenticator'), follow_redirects=True)
 		dump('mfa_setup_totp', r)
@@ -232,13 +221,13 @@ class TestMfaViews(UffdTestCase):
 		self.assertNotEqual(len(session.get('mfa_totp_key', '')), 0)
 
 	def test_setup_totp_without_recovery(self):
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('mfa.setup_totp', name='My TOTP Authenticator'), follow_redirects=True)
 		dump('mfa_setup_totp_without_recovery', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_setup_totp_finish(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
 		self.assertEqual(len(TOTPMethod.query.filter_by(dn=request.user.dn).all()), 0)
 		r = self.client.get(path=url_for('mfa.setup_totp', name='My TOTP Authenticator'), follow_redirects=True)
@@ -250,7 +239,7 @@ class TestMfaViews(UffdTestCase):
 		self.assertEqual(len(TOTPMethod.query.filter_by(dn=request.user.dn).all()), 1)
 
 	def test_setup_totp_finish_without_recovery(self):
-		self.login()
+		self.login_as('user')
 		self.assertEqual(len(TOTPMethod.query.filter_by(dn=request.user.dn).all()), 0)
 		r = self.client.get(path=url_for('mfa.setup_totp', name='My TOTP Authenticator'), follow_redirects=True)
 		method = TOTPMethod(request.user, key=session.get('mfa_totp_key', ''))
@@ -261,7 +250,7 @@ class TestMfaViews(UffdTestCase):
 		self.assertEqual(len(TOTPMethod.query.filter_by(dn=request.user.dn).all()), 0)
 
 	def test_setup_totp_finish_wrong_code(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
 		self.assertEqual(len(TOTPMethod.query.filter_by(dn=request.user.dn).all()), 0)
 		r = self.client.get(path=url_for('mfa.setup_totp', name='My TOTP Authenticator'), follow_redirects=True)
@@ -274,7 +263,7 @@ class TestMfaViews(UffdTestCase):
 		self.assertEqual(len(TOTPMethod.query.filter_by(dn=request.user.dn).all()), 0)
 
 	def test_setup_totp_finish_empty_code(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
 		self.assertEqual(len(TOTPMethod.query.filter_by(dn=request.user.dn).all()), 0)
 		r = self.client.get(path=url_for('mfa.setup_totp', name='My TOTP Authenticator'), follow_redirects=True)
@@ -284,7 +273,7 @@ class TestMfaViews(UffdTestCase):
 		self.assertEqual(len(TOTPMethod.query.filter_by(dn=request.user.dn).all()), 0)
 
 	def test_delete_totp(self):
-		self.login()
+		self.login_as('user')
 		self.add_recovery_codes()
 		self.add_totp()
 		method = TOTPMethod(request.user, name='test')
@@ -304,8 +293,7 @@ class TestMfaViews(UffdTestCase):
 		self.add_totp()
 		db.session.commit()
 		self.assertIsNone(request.user)
-		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
+		r = self.login_as('user')
 		dump('mfa_auth_redirected', r)
 		self.assertEqual(r.status_code, 200)
 		self.assertIn(b'/mfa/auth', r.data)
@@ -317,8 +305,7 @@ class TestMfaViews(UffdTestCase):
 
 	def test_auth_disabled(self):
 		self.assertIsNone(request.user)
-		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=False)
+		self.login_as('user')
 		r = self.client.get(path=url_for('mfa.auth', ref='/redirecttarget'), follow_redirects=False)
 		self.assertEqual(r.status_code, 302)
 		self.assertTrue(r.location.endswith('/redirecttarget'))
@@ -327,8 +314,7 @@ class TestMfaViews(UffdTestCase):
 	def test_auth_recovery_only(self):
 		self.add_recovery_codes()
 		self.assertIsNone(request.user)
-		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=False)
+		self.login_as('user')
 		r = self.client.get(path=url_for('mfa.auth', ref='/redirecttarget'), follow_redirects=False)
 		self.assertEqual(r.status_code, 302)
 		self.assertTrue(r.location.endswith('/redirecttarget'))
@@ -337,11 +323,11 @@ class TestMfaViews(UffdTestCase):
 	def test_auth_recovery_code(self):
 		self.add_recovery_codes()
 		self.add_totp()
-		method = RecoveryCodeMethod(user=get_user())
+		method = RecoveryCodeMethod(user=self.get_user())
 		db.session.add(method)
 		db.session.commit()
 		method_id = method.id
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('mfa.auth'), follow_redirects=False)
 		dump('mfa_auth_recovery_code', r)
 		self.assertEqual(r.status_code, 200)
@@ -355,11 +341,11 @@ class TestMfaViews(UffdTestCase):
 	def test_auth_totp_code(self):
 		self.add_recovery_codes()
 		self.add_totp()
-		method = TOTPMethod(user=get_user(), name='testname')
+		method = TOTPMethod(user=self.get_user(), name='testname')
 		raw_key = method.raw_key
 		db.session.add(method)
 		db.session.commit()
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('mfa.auth'), follow_redirects=False)
 		dump('mfa_auth_totp_code', r)
 		self.assertEqual(r.status_code, 200)
@@ -373,7 +359,7 @@ class TestMfaViews(UffdTestCase):
 	def test_auth_empty_code(self):
 		self.add_recovery_codes()
 		self.add_totp()
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('mfa.auth'), follow_redirects=False)
 		self.assertEqual(r.status_code, 200)
 		self.assertIsNone(request.user)
@@ -385,11 +371,11 @@ class TestMfaViews(UffdTestCase):
 	def test_auth_invalid_code(self):
 		self.add_recovery_codes()
 		self.add_totp()
-		method = TOTPMethod(user=get_user(), name='testname')
+		method = TOTPMethod(user=self.get_user(), name='testname')
 		raw_key = method.raw_key
 		db.session.add(method)
 		db.session.commit()
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('mfa.auth'), follow_redirects=False)
 		self.assertEqual(r.status_code, 200)
 		self.assertIsNone(request.user)
@@ -403,11 +389,11 @@ class TestMfaViews(UffdTestCase):
 	def test_auth_ratelimit(self):
 		self.add_recovery_codes()
 		self.add_totp()
-		method = TOTPMethod(user=get_user(), name='testname')
+		method = TOTPMethod(user=self.get_user(), name='testname')
 		raw_key = method.raw_key
 		db.session.add(method)
 		db.session.commit()
-		self.login()
+		self.login_as('user')
 		self.assertIsNone(request.user)
 		code = _hotp(int(time.time()/30), raw_key)
 		inv_code = str(int(code[0])+1)[-1] + code[1:]
diff --git a/tests/test_oauth2.py b/tests/test_oauth2.py
index 13d8b87ed8ac993a7730e11f8c39d8756c8fba3e..9cb2ac3e58bf6d4c7c321caf88621bc042ccd7df 100644
--- a/tests/test_oauth2.py
+++ b/tests/test_oauth2.py
@@ -13,11 +13,6 @@ from uffd import create_app, db, ldap
 
 from utils import dump, UffdTestCase
 
-def get_user():
-	return User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-
-def get_admin():
-	return User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
 
 class TestOAuth2Client(UffdTestCase):
 	def setUpApp(self):
@@ -39,8 +34,8 @@ class TestOAuth2Client(UffdTestCase):
 		self.assertEqual(client.required_group, 'users')
 
 	def test_access_allowed(self):
-		user = get_user() # has 'users' and 'uffd_access' group
-		admin = get_admin() # has 'users', 'uffd_access' and 'uffd_admin' group
+		user = self.get_user() # has 'users' and 'uffd_access' group
+		admin = self.get_admin() # has 'users', 'uffd_access' and 'uffd_admin' group
 		client = OAuth2Client('test', '', [''], ['uffd_admin', ['users', 'notagroup']])
 		self.assertFalse(client.access_allowed(user))
 		self.assertTrue(client.access_allowed(admin))
@@ -73,7 +68,7 @@ class TestViews(UffdTestCase):
 		r = self.client.get(path=url_for('oauth2.userinfo'), headers=[('Authorization', 'Bearer %s'%token)], follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
 		self.assertEqual(r.content_type, 'application/json')
-		user = get_user()
+		user = self.get_user()
 		self.assertEqual(r.json['id'], user.uid)
 		self.assertEqual(r.json['name'], user.displayname)
 		self.assertEqual(r.json['nickname'], user.loginname)
@@ -81,8 +76,7 @@ class TestViews(UffdTestCase):
 		self.assertTrue(r.json.get('groups'))
 
 	def test_authorization(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
+		self.login_as('user')
 		r = self.client.get(path=url_for('oauth2.authorize', response_type='code', client_id='test', state='teststate', redirect_uri='http://localhost:5009/callback'), follow_redirects=False)
 		self.assert_authorization(r)
 
@@ -100,7 +94,7 @@ class TestViews(UffdTestCase):
 		with self.client.session_transaction() as _session:
 			initiation = OAuth2DeviceLoginInitiation(oauth2_client_id='test')
 			db.session.add(initiation)
-			confirmation = DeviceLoginConfirmation(initiation=initiation, user=get_user())
+			confirmation = DeviceLoginConfirmation(initiation=initiation, user=self.get_user())
 			db.session.add(confirmation)
 			db.session.commit()
 			_session['devicelogin_id'] = initiation.id
diff --git a/tests/test_role.py b/tests/test_role.py
index dea9e108c1d62a0d9a75fe07d44e4f4a96890b69..6fef9547df589eca9aa3fc382bac471d9bdf7b11 100644
--- a/tests/test_role.py
+++ b/tests/test_role.py
@@ -41,8 +41,8 @@ class TestUserRoleAttributes(UffdTestCase):
 			ldap.session.delete(user)
 		ldap.session.add(User(loginname='service', is_service_user=True, mail='service@example.com', displayname='Service'))
 		ldap.session.commit()
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		service_user = User.query.get('uid=service,ou=users,dc=example,dc=com')
+		user = self.get_user()
+		service_user = User.query.get('uid=service,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		included_by_default_role = Role(name='included_by_default')
 		default_role = Role(name='default', is_default=True, included_roles=[included_by_default_role])
 		included_role = Role(name='included')
@@ -57,9 +57,9 @@ class TestUserRoleAttributes(UffdTestCase):
 		ldap.session.commit()
 
 	def test_compute_groups(self):
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		group1 = Group.query.get('cn=users,ou=groups,dc=example,dc=com')
-		group2 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')
+		user = self.get_user()
+		group1 = self.get_users_group()
+		group2 = self.get_access_group()
 		role1 = Role(name='role1', groups={group1: RoleGroup(group=group1)})
 		role2 = Role(name='role2', groups={group1: RoleGroup(group=group1), group2: RoleGroup(group=group2)})
 		db.session.add_all([role1, role2])
@@ -73,9 +73,9 @@ class TestUserRoleAttributes(UffdTestCase):
 		self.assertSetEqual(user.compute_groups(), {group1, group2})
 
 	def test_update_groups(self):
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		group1 = Group.query.get('cn=users,ou=groups,dc=example,dc=com')
-		group2 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')
+		user = self.get_user()
+		group1 = self.get_users_group()
+		group2 = self.get_access_group()
 		role1 = Role(name='role1', members=[user], groups={group1: RoleGroup(group=group1)})
 		role2 = Role(name='role2', groups={group2: RoleGroup(group=group2)})
 		db.session.add_all([role1, role2])
@@ -95,9 +95,9 @@ class TestRoleModel(UffdTestCase):
 			ldap.session.delete(user)
 		ldap.session.add(User(loginname='service', is_service_user=True, mail='service@example.com', displayname='Service'))
 		ldap.session.commit()
-		user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
-		service = User.query.get('uid=service,ou=users,dc=example,dc=com')
+		user1 = self.get_user()
+		user2 = self.get_admin()
+		service = User.query.get('uid=service,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		included_by_default_role = Role(name='included_by_default')
 		default_role = Role(name='default', is_default=True, included_roles=[included_by_default_role])
 		included_role = Role(name='included')
@@ -123,21 +123,21 @@ class TestRoleModel(UffdTestCase):
 		self.assertSetEqual(role3.included_roles_recursive, {baserole, role1, role2})
 
 	def test_groups_effective(self):
-		group1 = Group.query.get('cn=users,ou=groups,dc=example,dc=com')
-		group2 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')
+		group1 = self.get_users_group()
+		group2 = self.get_access_group()
 		baserole = Role(name='base', groups={group1: RoleGroup(group=group1)})
 		role1 = Role(name='role1', groups={group2: RoleGroup(group=group2)}, included_roles=[baserole])
 		self.assertSetEqual(baserole.groups_effective, {group1})
 		self.assertSetEqual(role1.groups_effective, {group1, group2})
 
 	def test_update_member_groups(self):
-		user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user1 = self.get_user()
 		user1.update_groups()
-		user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		user2 = self.get_admin()
 		user2.update_groups()
-		group1 = Group.query.get('cn=users,ou=groups,dc=example,dc=com')
-		group2 = Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')
-		group3 = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')
+		group1 = self.get_users_group()
+		group2 = self.get_access_group()
+		group3 = self.get_admin_group()
 		baserole = Role(name='base', members=[user1], groups={group1: RoleGroup(group=group1)})
 		role1 = Role(name='role1', members=[user2], groups={group2: RoleGroup(group=group2)}, included_roles=[baserole])
 		db.session.add_all([baserole, role1])
@@ -153,8 +153,7 @@ class TestRoleModel(UffdTestCase):
 class TestRoleViews(UffdTestCase):
 	def setUp(self):
 		super().setUp()
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testadmin', 'password': 'adminpassword'}, follow_redirects=True)
+		self.login_as('admin')
 
 	def test_index(self):
 		db.session.add(Role(name='base', description='Base role description'))
@@ -186,11 +185,11 @@ class TestRoleViews(UffdTestCase):
 		role = Role(name='base', description='Base role description')
 		db.session.add(role)
 		db.session.commit()
-		role.groups[Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')] = RoleGroup()
+		role.groups[self.get_admin_group()] = RoleGroup()
 		db.session.commit()
 		self.assertEqual(role.name, 'base')
 		self.assertEqual(role.description, 'Base role description')
-		self.assertEqual([group.dn for group in role.groups], ['cn=uffd_admin,ou=groups,dc=example,dc=com'])
+		self.assertEqual([group.dn for group in role.groups], [self.test_data.get('group_uffd_admin').get('dn')])
 		r = self.client.post(path=url_for('role.update', roleid=role.id),
 			data={'name': 'base1', 'description': 'Base role description1', 'moderator-group': '', 'group-20001': '1', 'group-20002': '1'},
 			follow_redirects=True)
@@ -199,8 +198,8 @@ class TestRoleViews(UffdTestCase):
 		role = Role.query.get(role.id)
 		self.assertEqual(role.name, 'base1')
 		self.assertEqual(role.description, 'Base role description1')
-		self.assertEqual(sorted([group.dn for group in role.groups]), ['cn=uffd_access,ou=groups,dc=example,dc=com',
-			'cn=users,ou=groups,dc=example,dc=com'])
+		self.assertEqual(sorted([group.dn for group in role.groups]), [self.test_data.get('group_uffd_access').get('dn'),
+		                                                               self.test_data.get('group_users').get('dn')])
 		# TODO: verify that group memberships are updated (currently not possible with ldap mock!)
 
 	def test_create(self):
@@ -214,14 +213,14 @@ class TestRoleViews(UffdTestCase):
 		self.assertIsNotNone(role)
 		self.assertEqual(role.name, 'base')
 		self.assertEqual(role.description, 'Base role description')
-		self.assertEqual(sorted([group.dn for group in role.groups]), ['cn=uffd_access,ou=groups,dc=example,dc=com',
-			'cn=users,ou=groups,dc=example,dc=com'])
+		self.assertEqual(sorted([group.dn for group in role.groups]), [self.test_data.get('group_uffd_access').get('dn'),
+		                                                               self.test_data.get('group_users').get('dn')])
 		# TODO: verify that group memberships are updated (currently not possible with ldap mock!)
 
 	def test_create_with_moderator_group(self):
 		self.assertIsNone(Role.query.filter_by(name='base').first())
 		r = self.client.post(path=url_for('role.update'),
-			data={'name': 'base', 'description': 'Base role description', 'moderator-group': 'cn=uffd_admin,ou=groups,dc=example,dc=com', 'group-20001': '1', 'group-20002': '1'},
+			data={'name': 'base', 'description': 'Base role description', 'moderator-group': self.test_data.get('group_uffd_admin').get('dn'), 'group-20001': '1', 'group-20002': '1'},
 			follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
 		role = Role.query.filter_by(name='base').first()
@@ -229,8 +228,8 @@ class TestRoleViews(UffdTestCase):
 		self.assertEqual(role.name, 'base')
 		self.assertEqual(role.description, 'Base role description')
 		self.assertEqual(role.moderator_group.name, 'uffd_admin')
-		self.assertEqual(sorted([group.dn for group in role.groups]), ['cn=uffd_access,ou=groups,dc=example,dc=com',
-			'cn=users,ou=groups,dc=example,dc=com'])
+		self.assertEqual(sorted([group.dn for group in role.groups]), [self.test_data.get('group_uffd_access').get('dn'),
+		                                                               self.test_data.get('group_users').get('dn')])
 		# TODO: verify that group memberships are updated (currently not possible with ldap mock!)
 
 	def test_delete(self):
@@ -252,9 +251,9 @@ class TestRoleViews(UffdTestCase):
 		ldap.session.commit()
 		role = Role(name='test')
 		db.session.add(role)
-		user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
-		service_user = User.query.get('uid=service,ou=users,dc=example,dc=com')
+		user1 = self.get_user()
+		user2 = self.get_admin()
+		service_user = User.query.get('uid=service,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertSetEqual(set(user1.roles_effective), set())
 		self.assertSetEqual(set(user2.roles_effective), set())
 		self.assertSetEqual(set(service_user.roles_effective), set())
@@ -270,7 +269,7 @@ class TestRoleViews(UffdTestCase):
 		dump('role_set_default', r)
 		self.assertEqual(r.status_code, 200)
 		role = Role.query.get(role_id)
-		service_user = User.query.get('uid=service,ou=users,dc=example,dc=com')
+		service_user = User.query.get('uid=service,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertSetEqual(set(role.members), {service_user})
 		self.assertSetEqual(set(user1.roles_effective), {role})
 		self.assertSetEqual(set(user2.roles_effective), {role})
@@ -284,9 +283,9 @@ class TestRoleViews(UffdTestCase):
 		ldap.session.commit()
 		role = Role(name='test', is_default=True)
 		db.session.add(role)
-		user1 = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-		user2 = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
-		service_user = User.query.get('uid=service,ou=users,dc=example,dc=com')
+		user1 = self.get_user()
+		user2 = self.get_admin()
+		service_user = User.query.get('uid=service,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		role.members.add(service_user)
 		self.assertSetEqual(set(user1.roles_effective), {role})
 		self.assertSetEqual(set(user2.roles_effective), {role})
@@ -298,7 +297,7 @@ class TestRoleViews(UffdTestCase):
 		dump('role_unset_default', r)
 		self.assertEqual(r.status_code, 200)
 		role = Role.query.get(role_id)
-		service_user = User.query.get('uid=service,ou=users,dc=example,dc=com')
+		service_user = User.query.get('uid=service,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertSetEqual(set(role.members), {service_user})
 		self.assertSetEqual(set(user1.roles_effective), set())
 		self.assertSetEqual(set(user2.roles_effective), set())
diff --git a/tests/test_rolemod.py b/tests/test_rolemod.py
index c178200aefcc5268bea43568d3a603151b77c413..d94fce37bda958fddcf99165bb76ac1c4c17d65f 100644
--- a/tests/test_rolemod.py
+++ b/tests/test_rolemod.py
@@ -7,31 +7,18 @@ from uffd.ldap import ldap
 
 from utils import dump, UffdTestCase
 
-class TestRolemodViews(UffdTestCase):
-	def login(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
-
+class TestRolemodViewsLoggedOut(UffdTestCase):
 	def test_acl_nologin(self):
 		r = self.client.get(path=url_for('rolemod.index'), follow_redirects=True)
 		dump('rolemod_acl_nologin', r)
 		self.assertEqual(r.status_code, 200)
 
-	def test_acl_notmod(self):
-		self.login()
-		db.session.add(Role(name='test', moderator_group=Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')))
-		db.session.commit()
-		r = self.client.get(path=url_for('rolemod.index'), follow_redirects=True)
-		dump('rolemod_acl_notmod', r)
-		self.assertEqual(r.status_code, 200)
-		self.assertIn('Access denied'.encode(), r.data)
-
 	def test_index(self):
-		db.session.add(Role(name='test_role_1', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')))
-		db.session.add(Role(name='test_role_2', moderator_group=Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')))
+		db.session.add(Role(name='test_role_1', moderator_group=self.get_access_group()))
+		db.session.add(Role(name='test_role_2', moderator_group=self.get_admin_group()))
 		db.session.add(Role(name='test_role_3'))
 		db.session.commit()
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('rolemod.index'), follow_redirects=True)
 		dump('rolemod_index', r)
 		self.assertEqual(r.status_code, 200)
@@ -39,19 +26,30 @@ class TestRolemodViews(UffdTestCase):
 		self.assertNotIn('test_role_2'.encode(), r.data)
 		self.assertNotIn('test_role_3'.encode(), r.data)
 
+class TestRolemodViews(UffdTestCase):
+	def setUp(self):
+		super().setUp()
+		self.login_as('user')
+
+	def test_acl_notmod(self):
+		db.session.add(Role(name='test', moderator_group=self.get_admin_group()))
+		db.session.commit()
+		r = self.client.get(path=url_for('rolemod.index'), follow_redirects=True)
+		dump('rolemod_acl_notmod', r)
+		self.assertEqual(r.status_code, 200)
+		self.assertIn('Access denied'.encode(), r.data)
+
 	def test_show(self):
-		self.login()
-		role = Role(name='test', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com'))
+		role = Role(name='test', moderator_group=self.get_access_group())
 		db.session.add(role)
-		role.members.add(User.query.get('uid=testadmin,ou=users,dc=example,dc=com'))
+		role.members.add(self.get_admin())
 		db.session.commit()
 		r = self.client.get(path=url_for('rolemod.show', role_id=role.id), follow_redirects=True)
 		dump('rolemod_show', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_show_empty(self):
-		self.login()
-		role = Role(name='test', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com'))
+		role = Role(name='test', moderator_group=self.get_access_group())
 		db.session.add(role)
 		db.session.commit()
 		r = self.client.get(path=url_for('rolemod.show', role_id=role.id), follow_redirects=True)
@@ -59,10 +57,9 @@ class TestRolemodViews(UffdTestCase):
 		self.assertEqual(r.status_code, 200)
 
 	def test_show_noperm(self):
-		self.login()
 		# Make sure we pass the blueprint-wide acl check
-		db.session.add(Role(name='other_role', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')))
-		role = Role(name='test', moderator_group=Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com'))
+		db.session.add(Role(name='other_role', moderator_group=self.get_access_group()))
+		role = Role(name='test', moderator_group=self.get_admin_group())
 		db.session.add(role)
 		db.session.commit()
 		r = self.client.get(path=url_for('rolemod.show', role_id=role.id), follow_redirects=True)
@@ -70,9 +67,8 @@ class TestRolemodViews(UffdTestCase):
 		self.assertIn('Access denied'.encode(), r.data)
 
 	def test_show_nomod(self):
-		self.login()
 		# Make sure we pass the blueprint-wide acl check
-		db.session.add(Role(name='other_role', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')))
+		db.session.add(Role(name='other_role', moderator_group=self.get_access_group()))
 		role = Role(name='test')
 		db.session.add(role)
 		db.session.commit()
@@ -81,18 +77,7 @@ class TestRolemodViews(UffdTestCase):
 		self.assertIn('Access denied'.encode(), r.data)
 
 	def test_update(self):
-		self.login()
-		role = Role(name='test', description='old_description', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com'))
-		db.session.add(role)
-		db.session.commit()
-		r = self.client.post(path=url_for('rolemod.update', role_id=role.id), data={'description': 'new_description'}, follow_redirects=True)
-		dump('rolemod_update', r)
-		self.assertEqual(r.status_code, 200)
-		self.assertEqual(Role.query.get(role.id).description, 'new_description')
-
-	def test_update(self):
-		self.login()
-		role = Role(name='test', description='old_description', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com'))
+		role = Role(name='test', description='old_description', moderator_group=self.get_access_group())
 		db.session.add(role)
 		db.session.commit()
 		r = self.client.post(path=url_for('rolemod.update', role_id=role.id), data={'description': 'new_description'}, follow_redirects=True)
@@ -101,8 +86,7 @@ class TestRolemodViews(UffdTestCase):
 		self.assertEqual(Role.query.get(role.id).description, 'new_description')
 
 	def test_update_descr_too_long(self):
-		self.login()
-		role = Role(name='test', description='old_description', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com'))
+		role = Role(name='test', description='old_description', moderator_group=self.get_access_group())
 		db.session.add(role)
 		db.session.commit()
 		r = self.client.post(path=url_for('rolemod.update', role_id=role.id), data={'description': 'long_description'*300}, follow_redirects=True)
@@ -111,10 +95,9 @@ class TestRolemodViews(UffdTestCase):
 		self.assertEqual(Role.query.get(role.id).description, 'old_description')
 
 	def test_update_noperm(self):
-		self.login()
 		# Make sure we pass the blueprint-wide acl check
-		db.session.add(Role(name='other_role', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')))
-		role = Role(name='test', description='old_description', moderator_group=Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com'))
+		db.session.add(Role(name='other_role', moderator_group=self.get_access_group()))
+		role = Role(name='test', description='old_description', moderator_group=self.get_admin_group())
 		db.session.add(role)
 		db.session.commit()
 		r = self.client.post(path=url_for('rolemod.update', role_id=role.id), data={'description': 'new_description'}, follow_redirects=True)
@@ -123,9 +106,8 @@ class TestRolemodViews(UffdTestCase):
 		self.assertEqual(Role.query.get(role.id).description, 'old_description')
 
 	def test_update_nomod(self):
-		self.login()
 		# Make sure we pass the blueprint-wide acl check
-		db.session.add(Role(name='other_role', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')))
+		db.session.add(Role(name='other_role', moderator_group=self.get_access_group()))
 		role = Role(name='test', description='old_description')
 		db.session.add(role)
 		db.session.commit()
@@ -135,72 +117,68 @@ class TestRolemodViews(UffdTestCase):
 		self.assertEqual(Role.query.get(role.id).description, 'old_description')
 
 	def test_delete_member(self):
-		self.login()
-		role = Role(name='test', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com'))
-		role.groups[Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')] = RoleGroup()
+		role = Role(name='test', moderator_group=self.get_access_group())
+		role.groups[self.get_admin_group()] = RoleGroup()
 		db.session.add(role)
-		role.members.add(User.query.get('uid=testadmin,ou=users,dc=example,dc=com'))
+		role.members.add(self.get_admin())
 		db.session.commit()
 		role.update_member_groups()
 		ldap.session.commit()
-		user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
-		group = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')
+		user = self.get_admin()
+		group = self.get_admin_group()
 		self.assertTrue(user in group.members)
 		role = Role.query.get(role.id)
 		self.assertTrue(user in role.members)
 		r = self.client.get(path=url_for('rolemod.delete_member', role_id=role.id, member_dn=user.dn), follow_redirects=True)
 		dump('rolemod_delete_member', r)
 		self.assertEqual(r.status_code, 200)
-		user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
-		group = Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')
-		self.assertFalse(user in group.members)
+		user_updated = self.get_admin()
+		group = self.get_admin_group()
+		self.assertFalse(user_updated in group.members)
 		role = Role.query.get(role.id)
-		self.assertFalse(user in role.members)
+		self.assertFalse(user_updated in role.members)
 
 	def test_delete_member_nomember(self):
-		self.login()
-		role = Role(name='test', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com'))
-		role.groups[Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com')] = RoleGroup()
+		role = Role(name='test', moderator_group=self.get_access_group())
+		role.groups[self.get_admin_group()] = RoleGroup()
 		db.session.add(role)
 		db.session.commit()
-		user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		user = self.get_admin()
 		r = self.client.get(path=url_for('rolemod.delete_member', role_id=role.id, member_dn=user.dn), follow_redirects=True)
 		dump('rolemod_delete_member_nomember', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_delete_member_noperm(self):
-		self.login()
 		# Make sure we pass the blueprint-wide acl check
-		db.session.add(Role(name='other_role', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')))
-		role = Role(name='test', moderator_group=Group.query.get('cn=uffd_admin,ou=groups,dc=example,dc=com'))
+		db.session.add(Role(name='other_role', moderator_group=self.get_access_group()))
+		role = Role(name='test', moderator_group=self.get_admin_group())
 		db.session.add(role)
-		role.members.add(User.query.get('uid=testadmin,ou=users,dc=example,dc=com'))
+		role.members.add(self.get_admin())
 		db.session.commit()
-		user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		user = self.get_admin()
 		role = Role.query.get(role.id)
 		self.assertTrue(user in role.members)
 		r = self.client.get(path=url_for('rolemod.delete_member', role_id=role.id, member_dn=user.dn), follow_redirects=True)
 		dump('rolemod_delete_member_noperm', r)
 		self.assertIn('Access denied'.encode(), r.data)
-		user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		user_updated = self.get_admin()
 		role = Role.query.get(role.id)
-		self.assertTrue(user in role.members)
+		self.assertTrue(user_updated in role.members)
 
 	def test_delete_member_nomod(self):
-		self.login()
 		# Make sure we pass the blueprint-wide acl check
-		db.session.add(Role(name='other_role', moderator_group=Group.query.get('cn=uffd_access,ou=groups,dc=example,dc=com')))
+		db.session.add(Role(name='other_role', moderator_group=self.get_access_group()))
 		role = Role(name='test')
 		db.session.add(role)
-		role.members.add(User.query.get('uid=testadmin,ou=users,dc=example,dc=com'))
+		role.members.add(self.get_admin())
 		db.session.commit()
-		user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		user = self.get_admin()
 		role = Role.query.get(role.id)
 		self.assertTrue(user in role.members)
 		r = self.client.get(path=url_for('rolemod.delete_member', role_id=role.id, member_dn=user.dn), follow_redirects=True)
 		dump('rolemod_delete_member_nomod', r)
 		self.assertIn('Access denied'.encode(), r.data)
-		user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		user_updated = self.get_admin()
 		role = Role.query.get(role.id)
-		self.assertTrue(user in role.members)
+		self.assertTrue(user_updated in role.members)
 
diff --git a/tests/test_selfservice.py b/tests/test_selfservice.py
index 6d5d96980406df9fd75fda7cf9aa41fe31ee36ec..c6018f2d6801f67935c64d0116625fe166081403 100644
--- a/tests/test_selfservice.py
+++ b/tests/test_selfservice.py
@@ -13,17 +13,9 @@ from uffd import create_app, db
 from utils import dump, UffdTestCase
 
 
-def get_user():
-	return User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-
-
 class TestSelfservice(UffdTestCase):
-	def login(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
-
 	def test_index(self):
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('selfservice.index'))
 		dump('selfservice_index', r)
 		self.assertEqual(r.status_code, 200)
@@ -33,7 +25,7 @@ class TestSelfservice(UffdTestCase):
 		self.assertIn(user.mail.encode(), r.data)
 
 	def test_update_displayname(self):
-		self.login()
+		self.login_as('user')
 		user = request.user
 		r = self.client.post(path=url_for('selfservice.update'),
 			data={'displayname': 'New Display Name', 'mail': user.mail, 'password': '', 'password1': ''},
@@ -44,7 +36,7 @@ class TestSelfservice(UffdTestCase):
 		self.assertEqual(_user.displayname, 'New Display Name')
 
 	def test_update_displayname_invalid(self):
-		self.login()
+		self.login_as('user')
 		user = request.user
 		r = self.client.post(path=url_for('selfservice.update'),
 			data={'displayname': '', 'mail': user.mail, 'password': '', 'password1': ''},
@@ -55,7 +47,7 @@ class TestSelfservice(UffdTestCase):
 		self.assertNotEqual(_user.displayname, '')
 
 	def test_update_mail(self):
-		self.login()
+		self.login_as('user')
 		user = request.user
 		r = self.client.post(path=url_for('selfservice.update'),
 			data={'displayname': user.displayname, 'mail': 'newemail@example.com', 'password': '', 'password1': ''},
@@ -74,7 +66,7 @@ class TestSelfservice(UffdTestCase):
 
 	def test_update_mail_sendfailure(self):
 		self.app.config['MAIL_SKIP_SEND'] = 'fail'
-		self.login()
+		self.login_as('user')
 		user = request.user
 		r = self.client.post(path=url_for('selfservice.update'),
 			data={'displayname': user.displayname, 'mail': 'newemail@example.com', 'password': '', 'password1': ''},
@@ -86,7 +78,7 @@ class TestSelfservice(UffdTestCase):
 		# Maybe also check that there is no new token in the db
 
 	def test_token_mail_emptydb(self):
-		self.login()
+		self.login_as('user')
 		user = request.user
 		r = self.client.get(path=url_for('selfservice.token_mail', token='A'*128), follow_redirects=True)
 		dump('token_mail_emptydb', r)
@@ -95,7 +87,7 @@ class TestSelfservice(UffdTestCase):
 		self.assertEqual(_user.mail, user.mail)
 
 	def test_token_mail_invalid(self):
-		self.login()
+		self.login_as('user')
 		user = request.user
 		db.session.add(MailToken(loginname=user.loginname, newmail='newusermail@example.com'))
 		db.session.commit()
@@ -107,9 +99,9 @@ class TestSelfservice(UffdTestCase):
 
 	@unittest.skip('See #26')
 	def test_token_mail_wrong_user(self):
-		self.login()
+		self.login_as('user')
 		user = request.user
-		admin_user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		admin_user = self.get_admin()
 		db.session.add(MailToken(loginname=user.loginname, newmail='newusermail@example.com'))
 		admin_token = MailToken(loginname='testadmin', newmail='newadminmail@example.com')
 		db.session.add(admin_token)
@@ -118,12 +110,12 @@ class TestSelfservice(UffdTestCase):
 		dump('token_mail_wrong_user', r)
 		self.assertEqual(r.status_code, 200)
 		_user = request.user
-		_admin_user = User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
+		_admin_user = self.get_admin()
 		self.assertEqual(_user.mail, user.mail)
 		self.assertEqual(_admin_user.mail, admin_user.mail)
 
 	def test_token_mail_expired(self):
-		self.login()
+		self.login_as('user')
 		user = request.user
 		token = MailToken(loginname=user.loginname, newmail='newusermail@example.com',
 			created=(datetime.datetime.now() - datetime.timedelta(days=10)))
@@ -140,7 +132,7 @@ class TestSelfservice(UffdTestCase):
 	def test_forgot_password(self):
 		if self.use_userconnection:
 			self.skipTest('Password Reset is not possible in user mode')
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user = self.get_user()
 		r = self.client.get(path=url_for('selfservice.forgot_password'))
 		dump('forgot_password', r)
 		self.assertEqual(r.status_code, 200)
@@ -155,7 +147,7 @@ class TestSelfservice(UffdTestCase):
 	def test_forgot_password_wrong_user(self):
 		if self.use_userconnection:
 			self.skipTest('Password Reset is not possible in user mode')
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user = self.get_user()
 		r = self.client.get(path=url_for('selfservice.forgot_password'))
 		self.assertEqual(r.status_code, 200)
 		r = self.client.post(path=url_for('selfservice.forgot_password'),
@@ -168,7 +160,7 @@ class TestSelfservice(UffdTestCase):
 	def test_forgot_password_wrong_email(self):
 		if self.use_userconnection:
 			self.skipTest('Password Reset is not possible in user mode')
-		user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		user = self.get_user()
 		r = self.client.get(path=url_for('selfservice.forgot_password'), follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
 		r = self.client.post(path=url_for('selfservice.forgot_password'),
@@ -192,7 +184,7 @@ class TestSelfservice(UffdTestCase):
 	def test_token_password(self):
 		if self.use_userconnection:
 			self.skipTest('Password Token is not possible in user mode')
-		user = get_user()
+		user = self.get_user()
 		token = PasswordToken(loginname=user.loginname)
 		db.session.add(token)
 		db.session.commit()
@@ -208,7 +200,7 @@ class TestSelfservice(UffdTestCase):
 	def test_token_password_emptydb(self):
 		if self.use_userconnection:
 			self.skipTest('Password Token is not possible in user mode')
-		user = get_user()
+		user = self.get_user()
 		r = self.client.get(path=url_for('selfservice.token_password', token='A'*128), follow_redirects=True)
 		dump('token_password_emptydb', r)
 		self.assertEqual(r.status_code, 200)
@@ -223,7 +215,7 @@ class TestSelfservice(UffdTestCase):
 	def test_token_password_invalid(self):
 		if self.use_userconnection:
 			self.skipTest('Password Token is not possible in user mode')
-		user = get_user()
+		user = self.get_user()
 		token = PasswordToken(loginname=user.loginname)
 		db.session.add(token)
 		db.session.commit()
@@ -241,7 +233,7 @@ class TestSelfservice(UffdTestCase):
 	def test_token_password_expired(self):
 		if self.use_userconnection:
 			self.skipTest('Password Token is not possible in user mode')
-		user = get_user()
+		user = self.get_user()
 		token = PasswordToken(loginname=user.loginname,
 			created=(datetime.datetime.now() - datetime.timedelta(days=10)))
 		db.session.add(token)
@@ -260,7 +252,7 @@ class TestSelfservice(UffdTestCase):
 	def test_token_password_different_passwords(self):
 		if self.use_userconnection:
 			self.skipTest('Password Token is not possible in user mode')
-		user = get_user()
+		user = self.get_user()
 		token = PasswordToken(loginname=user.loginname)
 		db.session.add(token)
 		db.session.commit()
diff --git a/tests/test_services.py b/tests/test_services.py
index f078a1b3ca293f2762ebede8d6519cd8674c0418..ab565077f11e3af3bd59087978f61498c3fa63ba 100644
--- a/tests/test_services.py
+++ b/tests/test_services.py
@@ -40,16 +40,12 @@ class TestServices(UffdTestCase):
 		]
 		self.app.config['SERVICES_PUBLIC'] = True
 
-	def login(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
-
 	def test_index(self):
 		r = self.client.get(path=url_for('services.index'))
 		dump('services_index_public', r)
 		self.assertEqual(r.status_code, 200)
 		self.assertNotIn(b'https://example.com/', r.data)
-		self.login()
+		self.login_as('user')
 		r = self.client.get(path=url_for('services.index'))
 		dump('services_index', r)
 		self.assertEqual(r.status_code, 200)
diff --git a/tests/test_session.py b/tests/test_session.py
index 74acf489ba6f83998909ec1fbf136e9f9c44b4c1..7509256b3f8736988adb70527de31e9ac6646a41 100644
--- a/tests/test_session.py
+++ b/tests/test_session.py
@@ -37,100 +37,98 @@ class TestSession(UffdTestCase):
 		self.assertIsNone(request.user)
 
 	def login(self):
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
+		self.login_as('user')
 		self.assertIsNotNone(request.user)
 
-	def assertLogin(self):
+	def assertLoggedIn(self):
 		self.assertIsNotNone(request.user)
-		self.assertEqual(self.client.get(path=url_for('test_login_required'),
-			follow_redirects=True).data, b'SUCCESS')
-		self.assertEqual(request.user.loginname, 'testuser')
+		self.assertEqual(self.client.get(path=url_for('test_login_required'), follow_redirects=True).data, b'SUCCESS')
+		self.assertEqual(request.user.loginname, self.get_user().loginname)
 
-	def assertLogout(self):
+	def assertLoggedOut(self):
 		self.assertIsNone(request.user)
 		self.assertNotEqual(self.client.get(path=url_for('test_login_required'),
-			follow_redirects=True).data, b'SUCCESS')
+							follow_redirects=True).data, b'SUCCESS')
 		self.assertEqual(request.user, None)
 
 	def test_login(self):
-		self.assertLogout()
+		self.assertLoggedOut()
 		r = self.client.get(path=url_for('session.login'), follow_redirects=True)
 		dump('login', r)
 		self.assertEqual(r.status_code, 200)
-		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
+		r = self.login_as('user')
 		dump('login_post', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertLogin()
+		self.assertLoggedIn()
 
 	def test_redirect(self):
-		r = self.client.post(path=url_for('session.login', ref=url_for('test_login_required')),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
+		r = self.login_as('user', ref=url_for('test_login_required'))
 		self.assertEqual(r.status_code, 200)
 		self.assertEqual(r.data, b'SUCCESS')
 
 	def test_wrong_password(self):
 		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'wrongpassword'}, follow_redirects=True)
+							data={'loginname': self.test_data.get('user').get('loginname'), 'password': 'wrongpassword'},
+							follow_redirects=True)
 		dump('login_wrong_password', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertLogout()
+		self.assertLoggedOut()
 
 	def test_empty_password(self):
 		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': ''}, follow_redirects=True)
+			data={'loginname': self.test_data.get('user').get('loginname'), 'password': ''}, follow_redirects=True)
 		dump('login_empty_password', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertLogout()
+		self.assertLoggedOut()
 
 	def test_wrong_user(self):
 		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': 'nouser', 'password': 'userpassword'}, follow_redirects=True)
+							data={'loginname': 'nouser', 'password': self.test_data.get('user').get('password')},
+							follow_redirects=True)
 		dump('login_wrong_user', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertLogout()
+		self.assertLoggedOut()
 
 	def test_empty_user(self):
 		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': '', 'password': 'userpassword'}, follow_redirects=True)
+			data={'loginname': '', 'password': self.test_data.get('user').get('password')}, follow_redirects=True)
 		dump('login_empty_user', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertLogout()
+		self.assertLoggedOut()
 
 	def test_no_access(self):
 		r = self.client.post(path=url_for('session.login'),
 			data={'loginname': 'testservice', 'password': 'servicepassword'}, follow_redirects=True)
 		dump('login_no_access', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertLogout()
+		self.assertLoggedOut()
 
 	def test_group_required(self):
 		self.login()
 		self.assertEqual(self.client.get(path=url_for('test_group_required1'),
-			follow_redirects=True).data, b'SUCCESS')
+										follow_redirects=True).data, b'SUCCESS')
 		self.assertNotEqual(self.client.get(path=url_for('test_group_required2'),
-			follow_redirects=True).data, b'SUCCESS')
+											follow_redirects=True).data, b'SUCCESS')
 
 	def test_logout(self):
 		self.login()
 		r = self.client.get(path=url_for('session.logout'), follow_redirects=True)
 		dump('logout', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertLogout()
+		self.assertLoggedOut()
 
 	@unittest.skip('See #29')
 	def test_timeout(self):
 		self.login()
 		time.sleep(3)
-		self.assertLogout()
+		self.assertLoggedOut()
 
 	def test_ratelimit(self):
 		for i in range(20):
 			self.client.post(path=url_for('session.login'),
-				data={'loginname': 'testuser', 'password': 'wrongpassword_%i'%i}, follow_redirects=True)
-		r = self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
+							data={'loginname': self.test_data.get('user').get('loginname'),
+								'password': 'wrongpassword_%i'%i}, follow_redirects=True)
+		r = self.login_as('user')
 		dump('login_ratelimit', r)
 		self.assertEqual(r.status_code, 200)
 		self.assertIsNone(request.user)
diff --git a/tests/test_signup.py b/tests/test_signup.py
index 65007789c8eb149bb5688b85ca5f964804c9e3db..3b940131e672f88e7ce3ea604b060094e5d86b92 100644
--- a/tests/test_signup.py
+++ b/tests/test_signup.py
@@ -125,7 +125,7 @@ class TestSignupModel(UffdTestCase):
 		if self.use_openldap:
 			self.assertIsNone(login_get_user('newuser', 'notsecret'))
 		self.assert_finish_success(signup, 'notsecret')
-		user = User.query.get('uid=newuser,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertEqual(user.loginname, 'newuser')
 		self.assertEqual(user.displayname, 'New User')
 		self.assertEqual(user.mail, 'test@example.com')
@@ -178,7 +178,7 @@ class TestSignupModel(UffdTestCase):
 		db_flush()
 		signup = Signup.query.get(signup1_token)
 		self.assert_finish_failure(signup, 'notsecret')
-		user = User.query.get('uid=newuser,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertEqual(user.mail, 'test2@example.com')
 
 class TestSignupModelOL(TestSignupModel):
@@ -351,11 +351,10 @@ class TestSignupViews(UffdTestCase):
 	def test_confirm_loggedin(self):
 		signup = Signup(loginname='newuser', displayname='New User', mail='test@example.com', password='notsecret')
 		signup = refetch_signup(signup)
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
+		self.login_as('user')
 		self.assertFalse(signup.completed)
 		self.assertIsNotNone(request.user)
-		self.assertEqual(request.user.loginname, 'testuser')
+		self.assertEqual(request.user.loginname, self.get_user().loginname)
 		r = self.client.get(path=url_for('signup.signup_confirm', token=signup.token), follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
 		r = self.client.post(path=url_for('signup.signup_confirm_submit', token=signup.token), follow_redirects=True, data={'password': 'notsecret'})
@@ -385,8 +384,8 @@ class TestSignupViews(UffdTestCase):
 		self.assertEqual(r.status_code, 200)
 
 	def test_confirm_completed(self):
-		signup = Signup(loginname='testuser', displayname='New User', mail='test@example.com', password='notsecret')
-		signup.user = User.query.get('uid=testuser,ou=users,dc=example,dc=com')
+		signup = Signup(loginname=self.get_user().loginname, displayname='New User', mail='test@example.com', password='notsecret')
+		signup.user = self.get_user()
 		signup = refetch_signup(signup)
 		self.assertTrue(signup.completed)
 		r = self.client.get(path=url_for('signup.signup_confirm', token=signup.token), follow_redirects=True)
@@ -406,7 +405,7 @@ class TestSignupViews(UffdTestCase):
 
 	def test_confirm_error(self):
 		# finish returns None and error message (here: because the user already exists)
-		signup = Signup(loginname='testuser', displayname='New User', mail='test@example.com', password='notsecret')
+		signup = Signup(loginname=self.get_user().loginname, displayname='New User', mail='test@example.com', password='notsecret')
 		signup = refetch_signup(signup)
 		r = self.client.post(path=url_for('signup.signup_confirm_submit', token=signup.token), follow_redirects=True, data={'password': 'notsecret'})
 		dump('test_signup_confirm_error', r)
diff --git a/tests/test_user.py b/tests/test_user.py
index 0caa4d752d3821e90e5b696ba67a4ae2fd75c2a2..3d5f53faa1a8350a0067c6f012a5c8da0907549a 100644
--- a/tests/test_user.py
+++ b/tests/test_user.py
@@ -13,35 +13,29 @@ from uffd import create_app, db
 from utils import dump, UffdTestCase
 
 
-def get_user():
-	return User.query.get('uid=testuser,ou=users,dc=example,dc=com')
-
-def get_admin():
-	return User.query.get('uid=testadmin,ou=users,dc=example,dc=com')
-
 class TestUserModel(UffdTestCase):
 	def test_has_permission(self):
-		user = get_user() # has 'users' and 'uffd_access' group
-		admin = get_admin() # has 'users', 'uffd_access' and 'uffd_admin' group
-		self.assertTrue(user.has_permission(None))
+		user_ = self.get_user() # has 'users' and 'uffd_access' group
+		admin = self.get_admin() # has 'users', 'uffd_access' and 'uffd_admin' group
+		self.assertTrue(user_.has_permission(None))
 		self.assertTrue(admin.has_permission(None))
-		self.assertTrue(user.has_permission('users'))
+		self.assertTrue(user_.has_permission('users'))
 		self.assertTrue(admin.has_permission('users'))
-		self.assertFalse(user.has_permission('notagroup'))
+		self.assertFalse(user_.has_permission('notagroup'))
 		self.assertFalse(admin.has_permission('notagroup'))
-		self.assertFalse(user.has_permission('uffd_admin'))
+		self.assertFalse(user_.has_permission('uffd_admin'))
 		self.assertTrue(admin.has_permission('uffd_admin'))
-		self.assertFalse(user.has_permission(['uffd_admin']))
+		self.assertFalse(user_.has_permission(['uffd_admin']))
 		self.assertTrue(admin.has_permission(['uffd_admin']))
-		self.assertFalse(user.has_permission(['uffd_admin', 'notagroup']))
+		self.assertFalse(user_.has_permission(['uffd_admin', 'notagroup']))
 		self.assertTrue(admin.has_permission(['uffd_admin', 'notagroup']))
-		self.assertFalse(user.has_permission(['notagroup', 'uffd_admin']))
+		self.assertFalse(user_.has_permission(['notagroup', 'uffd_admin']))
 		self.assertTrue(admin.has_permission(['notagroup', 'uffd_admin']))
-		self.assertTrue(user.has_permission(['uffd_admin', 'users']))
+		self.assertTrue(user_.has_permission(['uffd_admin', 'users']))
 		self.assertTrue(admin.has_permission(['uffd_admin', 'users']))
-		self.assertTrue(user.has_permission([['uffd_admin', 'users'], ['users', 'uffd_access']]))
+		self.assertTrue(user_.has_permission([['uffd_admin', 'users'], ['users', 'uffd_access']]))
 		self.assertTrue(admin.has_permission([['uffd_admin', 'users'], ['users', 'uffd_access']]))
-		self.assertFalse(user.has_permission(['uffd_admin', ['users', 'notagroup']]))
+		self.assertFalse(user_.has_permission(['uffd_admin', ['users', 'notagroup']]))
 		self.assertTrue(admin.has_permission(['uffd_admin', ['users', 'notagroup']]))
 
 class TestUserModelOL(TestUserModel):
@@ -52,14 +46,12 @@ class TestUserModelOLUser(TestUserModelOL):
 
 	def setUp(self):
 		super().setUp()
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testadmin', 'password': 'adminpassword'}, follow_redirects=True)
+		self.login_as('admin')
 
 class TestUserViews(UffdTestCase):
 	def setUp(self):
 		super().setUp()
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testadmin', 'password': 'adminpassword'}, follow_redirects=True)
+		self.login_as('admin')
 
 	def test_index(self):
 		r = self.client.get(path=url_for('user.index'), follow_redirects=True)
@@ -77,24 +69,24 @@ class TestUserViews(UffdTestCase):
 		r = self.client.get(path=url_for('user.show'), follow_redirects=True)
 		dump('user_new', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNone(User.query.get('uid=newuser,ou=users,dc=example,dc=com'))
+		self.assertIsNone(User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
 		r = self.client.post(path=url_for('user.update'),
 			data={'loginname': 'newuser', 'mail': 'newuser@example.com', 'displayname': 'New User',
 			f'role-{role1_id}': '1', 'password': 'newpassword'}, follow_redirects=True)
 		dump('user_new_submit', r)
 		self.assertEqual(r.status_code, 200)
-		user = User.query.get('uid=newuser,ou=users,dc=example,dc=com')
-		roles = sorted([r.name for r in user.roles_effective])
-		self.assertIsNotNone(user)
-		self.assertFalse(user.is_service_user)
-		self.assertEqual(user.loginname, 'newuser')
-		self.assertEqual(user.displayname, 'New User')
-		self.assertEqual(user.mail, 'newuser@example.com')
-		self.assertTrue(user.uid)
+		user_ = User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
+		roles = sorted([r.name for r in user_.roles_effective])
+		self.assertIsNotNone(user_)
+		self.assertFalse(user_.is_service_user)
+		self.assertEqual(user_.loginname, 'newuser')
+		self.assertEqual(user_.displayname, 'New User')
+		self.assertEqual(user_.mail, 'newuser@example.com')
+		self.assertTrue(user_.uid)
 		role1 = Role(name='role1')
 		self.assertEqual(roles, ['base', 'role1'])
 		# TODO: confirm Mail is send, login not yet possible
-		#self.assertTrue(ldap.test_user_bind(user.dn, 'newpassword'))
+		#self.assertTrue(ldap.test_user_bind(user_.dn, 'newpassword'))
 
 	def test_new_service(self):
 		db.session.add(Role(name='base', is_default=True))
@@ -107,13 +99,13 @@ class TestUserViews(UffdTestCase):
 		r = self.client.get(path=url_for('user.show'), follow_redirects=True)
 		dump('user_new_service', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNone(User.query.get('uid=newuser,ou=users,dc=example,dc=com'))
+		self.assertIsNone(User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
 		r = self.client.post(path=url_for('user.update'),
 			data={'loginname': 'newuser', 'mail': 'newuser@example.com', 'displayname': 'New User',
 			f'role-{role1_id}': '1', 'password': 'newpassword', 'serviceaccount': '1'}, follow_redirects=True)
 		dump('user_new_submit', r)
 		self.assertEqual(r.status_code, 200)
-		user = User.query.get('uid=newuser,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		roles = sorted([r.name for r in user.roles])
 		self.assertIsNotNone(user)
 		self.assertTrue(user.is_service_user)
@@ -132,7 +124,7 @@ class TestUserViews(UffdTestCase):
 			'password': 'newpassword'}, follow_redirects=True)
 		dump('user_new_invalid_loginname', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNone(User.query.get('uid=newuser,ou=users,dc=example,dc=com'))
+		self.assertIsNone(User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
 
 	def test_new_empty_loginname(self):
 		r = self.client.post(path=url_for('user.update'),
@@ -140,7 +132,7 @@ class TestUserViews(UffdTestCase):
 			'password': 'newpassword'}, follow_redirects=True)
 		dump('user_new_empty_loginname', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNone(User.query.get('uid=newuser,ou=users,dc=example,dc=com'))
+		self.assertIsNone(User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
 
 	def test_new_empty_email(self):
 		r = self.client.post(path=url_for('user.update'),
@@ -148,7 +140,7 @@ class TestUserViews(UffdTestCase):
 			'password': 'newpassword'}, follow_redirects=True)
 		dump('user_new_empty_email', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNone(User.query.get('uid=newuser,ou=users,dc=example,dc=com'))
+		self.assertIsNone(User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
 
 	def test_new_invalid_display_name(self):
 		r = self.client.post(path=url_for('user.update'),
@@ -156,109 +148,108 @@ class TestUserViews(UffdTestCase):
 			'password': 'newpassword'}, follow_redirects=True)
 		dump('user_new_invalid_display_name', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNone(User.query.get('uid=newuser,ou=users,dc=example,dc=com'))
+		self.assertIsNone(User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
 
 	def test_update(self):
-		user = get_user()
+		user_unupdated = self.get_user()
 		db.session.add(Role(name='base', is_default=True))
 		role1 = Role(name='role1')
 		db.session.add(role1)
 		role2 = Role(name='role2')
 		db.session.add(role2)
-		role2.members.add(user)
+		role2.members.add(user_unupdated)
 		db.session.commit()
 		role1_id = role1.id
-		r = self.client.get(path=url_for('user.show', uid=user.uid), follow_redirects=True)
+		r = self.client.get(path=url_for('user.show', uid=user_unupdated.uid), follow_redirects=True)
 		dump('user_update', r)
 		self.assertEqual(r.status_code, 200)
-		r = self.client.post(path=url_for('user.update', uid=user.uid),
+		r = self.client.post(path=url_for('user.update', uid=user_unupdated.uid),
 			data={'loginname': 'testuser', 'mail': 'newuser@example.com', 'displayname': 'New User',
 			f'role-{role1_id}': '1', 'password': ''}, follow_redirects=True)
 		dump('user_update_submit', r)
 		self.assertEqual(r.status_code, 200)
-		_user = get_user()
-		roles = sorted([r.name for r in _user.roles_effective])
-		self.assertEqual(_user.displayname, 'New User')
-		self.assertEqual(_user.mail, 'newuser@example.com')
-		self.assertEqual(_user.uid, user.uid)
-		self.assertEqual(_user.loginname, user.loginname)
-		self.assertTrue(ldap.test_user_bind(user.dn, 'userpassword'))
+		user_updated = self.get_user()
+		roles = sorted([r.name for r in user_updated.roles_effective])
+		self.assertEqual(user_updated.displayname, 'New User')
+		self.assertEqual(user_updated.mail, 'newuser@example.com')
+		self.assertEqual(user_updated.uid, user_unupdated.uid)
+		self.assertEqual(user_updated.loginname, user_unupdated.loginname)
+		print(user_updated.dn)
+		self.assertTrue(ldap.test_user_bind(user_updated.dn, self.test_data.get('user').get('password')))
 		self.assertEqual(roles, ['base', 'role1'])
 
 	def test_update_password(self):
-		user = get_user()
-		r = self.client.get(path=url_for('user.show', uid=user.uid), follow_redirects=True)
+		user_unupdated = self.get_user()
+		r = self.client.get(path=url_for('user.show', uid=user_unupdated.uid), follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
-		r = self.client.post(path=url_for('user.update', uid=user.uid),
+		r = self.client.post(path=url_for('user.update', uid=user_unupdated.uid),
 			data={'loginname': 'testuser', 'mail': 'newuser@example.com', 'displayname': 'New User',
 			'password': 'newpassword'}, follow_redirects=True)
 		dump('user_update_password', r)
 		self.assertEqual(r.status_code, 200)
-		_user = get_user()
-		self.assertEqual(_user.displayname, 'New User')
-		self.assertEqual(_user.mail, 'newuser@example.com')
-		self.assertEqual(_user.uid, user.uid)
-		self.assertEqual(_user.loginname, user.loginname)
-		self.assertTrue(ldap.test_user_bind(_user.dn, 'newpassword'))
-
+		user_updated = self.get_user()
+		self.assertEqual(user_updated.displayname, 'New User')
+		self.assertEqual(user_updated.mail, 'newuser@example.com')
+		self.assertEqual(user_updated.uid, user_unupdated.uid)
+		self.assertEqual(user_updated.loginname, user_unupdated.loginname)
+		self.assertTrue(ldap.test_user_bind(user_updated.dn, 'newpassword'))
 
 	@unittest.skip('See #28')
 	def test_update_invalid_password(self):
-		user = get_user()
-		r = self.client.get(path=url_for('user.show', uid=user.uid), follow_redirects=True)
+		user_unupdated = self.get_user()
+		r = self.client.get(path=url_for('user.show', uid=user_unupdated.uid), follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
-		r = self.client.post(path=url_for('user.update', uid=user.uid),
+		r = self.client.post(path=url_for('user.update', uid=user_unupdated.uid),
 			data={'loginname': 'testuser', 'mail': 'newuser@example.com', 'displayname': 'New User',
 			'password': 'A'}, follow_redirects=True)
 		dump('user_update_password', r)
 		self.assertEqual(r.status_code, 200)
-		_user = get_user()
-		self.assertFalse(ldap.test_user_bind(_user.dn, 'A'))
-		self.assertEqual(_user.displayname, user.displayname)
-		self.assertEqual(_user.mail, user.mail)
-		self.assertEqual(_user.loginname, user.loginname)
+		user_updated = self.get_user()
+		self.assertFalse(ldap.test_user_bind(user_updated.dn, 'A'))
+		self.assertEqual(user_updated.displayname, user_unupdated.displayname)
+		self.assertEqual(user_updated.mail, user_unupdated.mail)
+		self.assertEqual(user_updated.loginname, user_unupdated.loginname)
 
 	def test_update_empty_email(self):
-		user = get_user()
-		r = self.client.get(path=url_for('user.show', uid=user.uid), follow_redirects=True)
+		user_unupdated = self.get_user()
+		r = self.client.get(path=url_for('user.show', uid=user_unupdated.uid), follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
-		r = self.client.post(path=url_for('user.update', uid=user.uid),
+		r = self.client.post(path=url_for('user.update', uid=user_unupdated.uid),
 			data={'loginname': 'testuser', 'mail': '', 'displayname': 'New User',
 			'password': 'newpassword'}, follow_redirects=True)
 		dump('user_update_empty_mail', r)
 		self.assertEqual(r.status_code, 200)
-		_user = get_user()
-		self.assertEqual(_user.displayname, user.displayname)
-		self.assertEqual(_user.mail, user.mail)
-		self.assertEqual(_user.loginname, user.loginname)
-		self.assertFalse(ldap.test_user_bind(_user.dn, 'newpassword'))
+		user_updated = self.get_user()
+		self.assertEqual(user_updated.displayname, user_unupdated.displayname)
+		self.assertEqual(user_updated.mail, user_unupdated.mail)
+		self.assertEqual(user_updated.loginname, user_unupdated.loginname)
+		self.assertFalse(ldap.test_user_bind(user_updated.dn, 'newpassword'))
 
 	def test_update_invalid_display_name(self):
-		user = get_user()
-		r = self.client.get(path=url_for('user.show', uid=user.uid), follow_redirects=True)
+		user_unupdated = self.get_user()
+		r = self.client.get(path=url_for('user.show', uid=user_unupdated.uid), follow_redirects=True)
 		self.assertEqual(r.status_code, 200)
-		r = self.client.post(path=url_for('user.update', uid=user.uid),
+		r = self.client.post(path=url_for('user.update', uid=user_unupdated.uid),
 			data={'loginname': 'testuser', 'mail': 'newuser@example.com', 'displayname': 'A'*200,
 			'password': 'newpassword'}, follow_redirects=True)
 		dump('user_update_invalid_display_name', r)
 		self.assertEqual(r.status_code, 200)
-		_user = get_user()
-		self.assertEqual(_user.displayname, user.displayname)
-		self.assertEqual(_user.mail, user.mail)
-		self.assertEqual(_user.loginname, user.loginname)
-		self.assertFalse(ldap.test_user_bind(_user.dn, 'newpassword'))
+		user_updated = self.get_user()
+		self.assertEqual(user_updated.displayname, user_unupdated.displayname)
+		self.assertEqual(user_updated.mail, user_unupdated.mail)
+		self.assertEqual(user_updated.loginname, user_unupdated.loginname)
+		self.assertFalse(ldap.test_user_bind(user_updated.dn, 'newpassword'))
 
 	def test_show(self):
-		r = self.client.get(path=url_for('user.show', uid=get_user().uid), follow_redirects=True)
+		r = self.client.get(path=url_for('user.show', uid=self.get_user().uid), follow_redirects=True)
 		dump('user_show', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_delete(self):
-		user = get_user()
-		r = self.client.get(path=url_for('user.delete', uid=user.uid), follow_redirects=True)
+		r = self.client.get(path=url_for('user.delete', uid=self.get_user().uid), follow_redirects=True)
 		dump('user_delete', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNone(get_user())
+		self.assertIsNone(self.get_user())
 
 	def test_csvimport(self):
 		role1 = Role(name='role1')
@@ -286,68 +277,67 @@ newuser12,newuser12@example.com,{role1.id};{role1.id}
 		r = self.client.post(path=url_for('user.csvimport'), data={'csv': data}, follow_redirects=True)
 		dump('user_csvimport', r)
 		self.assertEqual(r.status_code, 200)
-		user = User.query.get('uid=newuser1,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser1,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser1')
 		self.assertEqual(user.displayname, 'newuser1')
 		self.assertEqual(user.mail, 'newuser1@example.com')
 		roles = sorted([r.name for r in user.roles])
 		self.assertEqual(roles, [])
-		user = User.query.get('uid=newuser2,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser2,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser2')
 		self.assertEqual(user.displayname, 'newuser2')
 		self.assertEqual(user.mail, 'newuser2@example.com')
 		roles = sorted([r.name for r in user.roles])
 		self.assertEqual(roles, ['role1'])
-		user = User.query.get('uid=newuser3,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser3,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser3')
 		self.assertEqual(user.displayname, 'newuser3')
 		self.assertEqual(user.mail, 'newuser3@example.com')
 		roles = sorted([r.name for r in user.roles])
 		self.assertEqual(roles, ['role1', 'role2'])
-		user = User.query.get('uid=newuser4,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser4,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser4')
 		self.assertEqual(user.displayname, 'newuser4')
 		self.assertEqual(user.mail, 'newuser4@example.com')
 		roles = sorted([r.name for r in user.roles])
 		self.assertEqual(roles, [])
-		user = User.query.get('uid=newuser5,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser5,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser5')
 		self.assertEqual(user.displayname, 'newuser5')
 		self.assertEqual(user.mail, 'newuser5@example.com')
 		roles = sorted([r.name for r in user.roles])
 		self.assertEqual(roles, [])
-		user = User.query.get('uid=newuser6,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser6,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser6')
 		self.assertEqual(user.displayname, 'newuser6')
 		self.assertEqual(user.mail, 'newuser6@example.com')
 		roles = sorted([r.name for r in user.roles])
 		self.assertEqual(roles, ['role1', 'role2'])
-		self.assertIsNone(User.query.get('uid=newuser7,ou=users,dc=example,dc=com'))
-		self.assertIsNone(User.query.get('uid=newuser8,ou=users,dc=example,dc=com'))
-		self.assertIsNone(User.query.get('uid=newuser9,ou=users,dc=example,dc=com'))
-		user = User.query.get('uid=newuser10,ou=users,dc=example,dc=com')
+		self.assertIsNone(User.query.get('uid=newuser7,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
+		self.assertIsNone(User.query.get('uid=newuser8,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
+		self.assertIsNone(User.query.get('uid=newuser9,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
+		user = User.query.get('uid=newuser10,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser10')
 		self.assertEqual(user.displayname, 'newuser10')
 		self.assertEqual(user.mail, 'newuser10@example.com')
 		roles = sorted([r.name for r in user.roles])
 		self.assertEqual(roles, [])
-		user = User.query.get('uid=newuser11,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser11,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser11')
 		self.assertEqual(user.displayname, 'newuser11')
 		self.assertEqual(user.mail, 'newuser11@example.com')
 		# Currently the csv import is not very robust, imho newuser11 should have role1 and role2!
 		roles = sorted([r.name for r in user.roles])
-		#self.assertEqual(roles, ['role1', 'role2'])
 		self.assertEqual(roles, ['role2'])
-		user = User.query.get('uid=newuser12,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser12,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNotNone(user)
 		self.assertEqual(user.loginname, 'newuser12')
 		self.assertEqual(user.displayname, 'newuser12')
@@ -367,18 +357,15 @@ class TestUserViewsOLUserAsUser(UffdTestCase):
 
 	def setUp(self):
 		super().setUp()
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testuser', 'password': 'userpassword'}, follow_redirects=True)
+		self.login_as('user')
 
 	def test_view_own(self):
-		user_ = get_user()
-		r = self.client.get(path=url_for('user.show', uid=user_.uid), follow_redirects=True)
+		r = self.client.get(path=url_for('user.show', uid=self.get_user().uid), follow_redirects=True)
 		dump('user_view_own', r)
 		self.assertEqual(r.status_code, 200)
 
 	def test_view_others(self):
-		admin = get_admin()
-		r = self.client.get(path=url_for('user.show', uid=admin.uid), follow_redirects=True)
+		r = self.client.get(path=url_for('user.show', uid=self.get_admin().uid), follow_redirects=True)
 		dump('user_view_others', r)
 		self.assertEqual(r.status_code, 200)
 
@@ -388,7 +375,7 @@ class TestUserViewsOLUserAsUser(UffdTestCase):
 		self.assertEqual(r.status_code, 200)
 
 	def test_update_other_user(self):
-		user_ = get_admin()
+		user_ = self.get_admin()
 		db.session.add(Role(name='base', is_default=True))
 		role1 = Role(name='role1')
 		db.session.add(role1)
@@ -405,7 +392,7 @@ class TestUserViewsOLUserAsUser(UffdTestCase):
 			f'role-{role1_id}': '1', 'password': ''}, follow_redirects=True)
 		dump('user_update_submit', r)
 		self.assertEqual(r.status_code, 200)
-		_user = get_admin()
+		_user = self.get_admin()
 		self.assertEqual(_user.displayname, user_.displayname)
 		self.assertEqual(_user.mail, user_.mail)
 		self.assertEqual(_user.uid, user_.uid)
@@ -422,28 +409,26 @@ class TestUserViewsOLUserAsUser(UffdTestCase):
 		r = self.client.get(path=url_for('user.show'), follow_redirects=True)
 		dump('user_new', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNone(User.query.get('uid=newuser,ou=users,dc=example,dc=com'))
+		self.assertIsNone(User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE'])))
 		r = self.client.post(path=url_for('user.update'),
 			data={'loginname': 'newuser', 'mail': 'newuser@example.com', 'displayname': 'New User',
 			f'role-{role1_id}': '1', 'password': 'newpassword'}, follow_redirects=True)
 		dump('user_new_submit', r)
 		self.assertEqual(r.status_code, 200)
-		user = User.query.get('uid=newuser,ou=users,dc=example,dc=com')
+		user = User.query.get('uid=newuser,{}'.format(self.app.config['LDAP_USER_SEARCH_BASE']))
 		self.assertIsNone(user)
 
 	def test_delete(self):
-		user = get_admin()
-		r = self.client.get(path=url_for('user.delete', uid=user.uid), follow_redirects=True)
+		r = self.client.get(path=url_for('user.delete', uid=self.get_admin().uid), follow_redirects=True)
 		dump('user_delete', r)
 		self.assertEqual(r.status_code, 200)
-		self.assertIsNotNone(get_admin())
+		self.assertIsNotNone(self.get_admin())
 
 
 class TestGroupViews(UffdTestCase):
 	def setUp(self):
 		super().setUp()
-		self.client.post(path=url_for('session.login'),
-			data={'loginname': 'testadmin', 'password': 'adminpassword'}, follow_redirects=True)
+		self.login_as('admin')
 
 	def test_index(self):
 		r = self.client.get(path=url_for('group.index'), follow_redirects=True)
diff --git a/tests/utils.py b/tests/utils.py
index 3d198c551dece375a96ab53650e28172f8035edf..ee4b57624d312845b04d9626a204c04f40d9ebfe 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -3,9 +3,10 @@ import tempfile
 import shutil
 import unittest
 
-from flask import request
+from flask import request, url_for
 
 from uffd import create_app, db
+from uffd.user.models import User, Group
 
 def dump(basename, resp):
 	basename = basename.replace('.', '_').replace('/', '_')
@@ -27,6 +28,26 @@ class UffdTestCase(unittest.TestCase):
 	use_openldap = False
 	use_userconnection = False
 
+	def get_user(self):
+		return User.query.get(self.test_data.get('user').get('dn'))
+
+	def get_admin(self):
+		return User.query.get(self.test_data.get('admin').get('dn'))
+
+	def get_admin_group(self):
+		return Group.query.get(self.test_data.get('group_uffd_admin').get('dn'))
+
+	def get_access_group(self):
+		return Group.query.get(self.test_data.get('group_uffd_access').get('dn'))
+
+	def get_users_group(self):
+		return Group.query.get(self.test_data.get('group_users').get('dn'))
+
+	def login_as(self, user, ref=None):
+		return self.client.post(path=url_for('session.login', ref=ref),
+								data={'loginname': self.test_data.get(user).get('loginname'),
+									'password': self.test_data.get(user).get('password')}, follow_redirects=True)
+
 	def setUp(self):
 		self.dir = tempfile.mkdtemp()
 		# It would be far better to create a minimal app here, but since the
@@ -55,10 +76,33 @@ class UffdTestCase(unittest.TestCase):
 			else:
 				config['LDAP_SERVICE_BIND_DN'] = 'cn=uffd,ou=system,dc=example,dc=com'
 			config['LDAP_SERVICE_BIND_PASSWORD'] = 'uffd-ldap-password'
-			os.system("ldapdelete -c -D 'cn=uffd,ou=system,dc=example,dc=com' -w 'uffd-ldap-password' -H 'ldap://localhost' -f ldap_server_entries_cleanup.ldif > /dev/null 2>&1")
-			os.system("ldapadd -c -D 'cn=uffd,ou=system,dc=example,dc=com' -w 'uffd-ldap-password' -H 'ldap://localhost' -f ldap_server_entries_add.ldif")
-			os.system("ldapmodify -c -D 'cn=uffd,ou=system,dc=example,dc=com' -w 'uffd-ldap-password' -H 'ldap://localhost' -f ldap_server_entries_modify.ldif")
+			os.system("ldapdelete -c -D 'cn=uffd,ou=system,dc=example,dc=com' -w '{}' -H '{}' -f tests/openldap_ldifs/ldap_server_entries_cleanup.ldif > /dev/null 2>&1".format(config['LDAP_SERVICE_BIND_PASSWORD'], config['LDAP_SERVICE_URL']))
+			os.system("ldapadd -c -D 'cn=uffd,ou=system,dc=example,dc=com' -w '{}' -H '{}' -f tests/openldap_ldifs/ldap_server_entries_add.ldif".format(config['LDAP_SERVICE_BIND_PASSWORD'], config['LDAP_SERVICE_URL']))
+			os.system("ldapmodify -c -D 'cn=uffd,ou=system,dc=example,dc=com' -w '{}' -H '{}' -f tests/openldap_ldifs/ldap_server_entries_modify.ldif".format(config['LDAP_SERVICE_BIND_PASSWORD'], config['LDAP_SERVICE_URL']))
 			#os.system("/usr/sbin/slapcat -n 1 -l /dev/stdout")
+
+		self.test_data = {
+			'admin': {
+				'loginname': 'testadmin',
+				'dn': 'uid=testadmin,ou=users,dc=example,dc=com',
+				'password': 'adminpassword'
+			},
+			'user': {
+				'loginname': 'testuser',
+				'dn': 'uid=testuser,ou=users,dc=example,dc=com',
+				'password': 'userpassword'
+			},
+			'group_uffd_access': {
+				'dn': 'cn=uffd_access,ou=groups,dc=example,dc=com'
+			},
+			'group_uffd_admin': {
+				'dn': 'cn=uffd_admin,ou=groups,dc=example,dc=com'
+			},
+			'group_users': {
+				'dn': 'cn=users,ou=groups,dc=example,dc=com'
+			}
+		}
+
 		self.app = create_app(config)
 		self.setUpApp()
 		self.client = self.app.test_client()
diff --git a/uffd/ldap.py b/uffd/ldap.py
index 1d87efe8bc97e75dda48ebb0677fbc3ce1a75ada..be03350ee56f9ea0086f7b9f4251fe53b5a890d4 100644
--- a/uffd/ldap.py
+++ b/uffd/ldap.py
@@ -122,9 +122,10 @@ class FlaskLDAPMapper(LDAPMapper):
 			# changes persistent across requests we reuse the same `Connection` object
 			# for all calls to `service_conn()` and `user_conn()`.
 			if not hasattr(current_app, 'ldap_mock'):
-				server = ldap3.Server.from_definition('ldap_mock', 'ldap_server_info.json', 'ldap_server_schema.json')
+				server = ldap3.Server.from_definition('ldap_mock', 'tests/openldap_mock/ldap_server_info.json',
+				                                      'tests/openldap_mock/ldap_server_schema.json')
 				current_app.ldap_mock = ldap3.Connection(server, client_strategy=ldap3.MOCK_SYNC)
-				current_app.ldap_mock.strategy.entries_from_json('ldap_server_entries.json')
+				current_app.ldap_mock.strategy.entries_from_json('tests/openldap_mock/ldap_server_entries.json')
 				current_app.ldap_mock.bind()
 			return current_app.ldap_mock
 		server = ldap3.Server(current_app.config["LDAP_SERVICE_URL"], get_info=ldap3.ALL)