diff --git a/docs/examples/faker2filecopy/config.yml b/docs/examples/copy_faker2file/config.yml
similarity index 100%
rename from docs/examples/faker2filecopy/config.yml
rename to docs/examples/copy_faker2file/config.yml
diff --git a/docs/examples/faker2filecopy/data/expected_fakeperson.csv b/docs/examples/copy_faker2file/data/expected_fakeperson.csv
similarity index 100%
rename from docs/examples/faker2filecopy/data/expected_fakeperson.csv
rename to docs/examples/copy_faker2file/data/expected_fakeperson.csv
diff --git a/docs/examples/sqlite2filecopy/config.yml b/docs/examples/copy_sqlite2file/config.yml
similarity index 100%
rename from docs/examples/sqlite2filecopy/config.yml
rename to docs/examples/copy_sqlite2file/config.yml
diff --git a/docs/examples/sqlite2filecopy/data/expected_person.csv b/docs/examples/copy_sqlite2file/data/expected_person.csv
similarity index 100%
rename from docs/examples/sqlite2filecopy/data/expected_person.csv
rename to docs/examples/copy_sqlite2file/data/expected_person.csv
diff --git a/docs/examples/sqlite2filecopy/data/person.sqlite3 b/docs/examples/copy_sqlite2file/data/person.sqlite3
similarity index 100%
rename from docs/examples/sqlite2filecopy/data/person.sqlite3
rename to docs/examples/copy_sqlite2file/data/person.sqlite3
diff --git a/docs/examples/file2sqlitemultipleidentifiers/config.yml b/docs/examples/eetl_file2sqliteWithMultipleIdentifiers/config.yml
similarity index 100%
rename from docs/examples/file2sqlitemultipleidentifiers/config.yml
rename to docs/examples/eetl_file2sqliteWithMultipleIdentifiers/config.yml
diff --git a/docs/examples/file2sqlitemultipleidentifiers/data/person.csv b/docs/examples/eetl_file2sqliteWithMultipleIdentifiers/data/person.csv
similarity index 100%
rename from docs/examples/file2sqlitemultipleidentifiers/data/person.csv
rename to docs/examples/eetl_file2sqliteWithMultipleIdentifiers/data/person.csv
diff --git a/docs/examples/sqlquery/config.yml b/docs/examples/query_sqlquery2sqlite/config.yml
similarity index 100%
rename from docs/examples/sqlquery/config.yml
rename to docs/examples/query_sqlquery2sqlite/config.yml
diff --git a/docs/examples/file2sqlitesync/config.yml b/docs/examples/sync_file2sqlite/config.yml
similarity index 100%
rename from docs/examples/file2sqlitesync/config.yml
rename to docs/examples/sync_file2sqlite/config.yml
diff --git a/docs/examples/file2sqlitesync/data/person.csv b/docs/examples/sync_file2sqlite/data/person.csv
similarity index 100%
rename from docs/examples/file2sqlitesync/data/person.csv
rename to docs/examples/sync_file2sqlite/data/person.csv
diff --git a/docs/examples/ldap2file/config.yml b/docs/examples/sync_ldap2file/config.yml
similarity index 97%
rename from docs/examples/ldap2file/config.yml
rename to docs/examples/sync_ldap2file/config.yml
index ca18f71f6e4aa7826fbbaf376fb85f077701abfc..e1a6669a237cb120989dbe41a8c30875b22f647b 100644
--- a/docs/examples/ldap2file/config.yml
+++ b/docs/examples/sync_ldap2file/config.yml
@@ -37,7 +37,7 @@ entities:
 ---
 ###############################################################################
 # The third and last YAML document defines what you want to do.
-# Define this by using jobs shipped from hshetl. 
+# Define this by using jobs shipped from hshetl.
 ###############################################################################
 jobs:
   -
diff --git a/docs/examples/sqlite2ldap/config.yml b/docs/examples/sync_sqlite2ldap/config.yml
similarity index 98%
rename from docs/examples/sqlite2ldap/config.yml
rename to docs/examples/sync_sqlite2ldap/config.yml
index 8dcd8791df385a38c9a0e7eb1baa4b6d32e1b18a..76598aa2a4176de1ae28c5e33415ea74f2231222 100644
--- a/docs/examples/sqlite2ldap/config.yml
+++ b/docs/examples/sync_sqlite2ldap/config.yml
@@ -15,13 +15,13 @@ connectors:
     encoding: 'latin-1'
     start_tls: FALSE
     base: cn=testing,dc=foobar
-    scope: subtree 
+    scope: subtree
   -
     !sqlite
     name: localsqlite
     uri: 'sqlite:///./person.sqlite3'
     encoding: 'utf-8'
---- 
+---
 ###############################################################################
 # The second YAML document defines the entities that will be used for all
 # operations on your data.
@@ -36,7 +36,7 @@ entities:
       cn: string
       mail: string
       sn: string
---- 
+---
 ###############################################################################
 # The third and last YAML document defines what you want to do.
 # Define this by using jobs shipped from hshetl.
diff --git a/docs/examples/sqlite2ldap/person.sqlite3 b/docs/examples/sync_sqlite2ldap/person.sqlite3
similarity index 100%
rename from docs/examples/sqlite2ldap/person.sqlite3
rename to docs/examples/sync_sqlite2ldap/person.sqlite3
diff --git a/hshetl/test/functional/__init__.py b/hshetl/test/functional/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4ac3dac269c2e538a2967d76f744d6404da106e0 100644
--- a/hshetl/test/functional/__init__.py
+++ b/hshetl/test/functional/__init__.py
@@ -0,0 +1,22 @@
+import unittest
+import sys
+import os
+import shutil
+import sqlite3
+
+
+class TestBaseClass(unittest.TestCase):
+
+    example_dir_name = None
+
+    def setUp(self):
+        self.current_dir = os.getcwd()
+        self.fixture_dir = os.path.dirname(__file__) + '/../../../docs/examples/' + self.example_dir_name + '/'
+        self.test_dir = '/tmp/hshetl_test/'
+        self.test_working_directory = '/tmp/hshetl_test/' + self.example_dir_name + '/'
+        os.makedirs(self.test_dir)
+        shutil.copytree(self.fixture_dir, self.test_working_directory)
+
+    def tearDown(self):
+        os.chdir(self.current_dir)
+        shutil.rmtree(self.test_dir)
diff --git a/hshetl/test/functional/test_copy.py b/hshetl/test/functional/test_copy.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1e8f10f58ad6834b77adc956cdabf09b3860235
--- /dev/null
+++ b/hshetl/test/functional/test_copy.py
@@ -0,0 +1,18 @@
+from hshetl.test.functional import TestBaseClass
+from hshetl.cli import Controller
+import sys
+import filecmp
+
+
+class TestCopyJob(TestBaseClass):
+
+    example_dir_name = 'copy_sqlite2file'
+
+    def setUp(self):
+        super(TestCopyJob, self).setUp()
+        sys.argv = ['hshetl', '-d', self.test_working_directory]
+
+
+    def test_job(self):
+        Controller().configure().execute()
+        self.assertTrue(filecmp.cmp(self.test_working_directory + 'data/expected_person.csv', self.test_working_directory + 'person.csv'))
diff --git a/hshetl/test/functional/test_copy_faker2file.py b/hshetl/test/functional/test_copy_faker2file.py
new file mode 100644
index 0000000000000000000000000000000000000000..4cd87e8adcbf6a61f8cac42cabd7aec0583ce4de
--- /dev/null
+++ b/hshetl/test/functional/test_copy_faker2file.py
@@ -0,0 +1,18 @@
+from hshetl.test.functional import TestBaseClass
+from hshetl.cli import Controller
+import sys
+import filecmp
+
+
+class TestFakerCopyJob(TestBaseClass):
+
+    example_dir_name = 'copy_faker2file'
+
+    def setUp(self):
+        super(TestFakerCopyJob, self).setUp()
+        sys.argv = ['hshetl', '-d', self.test_working_directory]
+
+
+    def test_job(self):
+        Controller().configure().execute()
+        self.assertTrue(filecmp.cmp(self.test_working_directory + 'data/expected_fakeperson.csv', self.test_working_directory + 'fakeperson.csv'))
\ No newline at end of file
diff --git a/hshetl/test/functional/test_eetl_file2sqliteWithMultipleIdentifiers.py b/hshetl/test/functional/test_eetl_file2sqliteWithMultipleIdentifiers.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a528af946d120a1beb1a02cf9b202fcc5f57e4c
--- /dev/null
+++ b/hshetl/test/functional/test_eetl_file2sqliteWithMultipleIdentifiers.py
@@ -0,0 +1,37 @@
+from hshetl.test.functional import TestBaseClass
+from hshetl.cli import Controller
+import sys
+import sqlite3
+
+class TestFileToSQLiteWithMultipleIdentifiers(TestBaseClass):
+
+    example_dir_name = 'eetl_file2sqliteWithMultipleIdentifiers'
+
+    def setUp(self):
+        super(TestFileToSQLiteWithMultipleIdentifiers, self).setUp()
+        self.conn = sqlite3.connect(self.test_working_directory + 'person.sqlite3')
+        self.cursor = self.conn.cursor()
+        self.cursor.execute('CREATE TABLE user (name VARCHAR(50), first_name VARCHAR(255), inactive BOOL, foreign_id INT, telephone INT);')
+        self.conn.commit()
+        sys.argv = ['hshetl', '-d', self.test_working_directory]
+
+    def tearDown(self):
+        super(TestFileToSQLiteWithMultipleIdentifiers, self).tearDown()
+        self.conn.close()
+
+
+    def test_sync_handles_insert_update_and_delete_simultaneously(self):
+        expected_result = [(u'Mueller', u'Hannah', 1, 100, 67466035),
+                           (u'Mueller', u'Robert', 1, 102, 39447759),
+                           (u'Meier', u'David', 1, 106, 70673167),
+                           (u'Meier', u'Ingrid', 1, 108, 14499323),
+                           (u'Mustermann', u'Max', 0, 110, 12345567)]
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,first_name,name,telephone) VALUES (100, 0, \'Hannah\', \'Mueller\', 12345678)')
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,first_name,name,telephone) VALUES (100, 0, \'Robert\', \'Mueller\', 67466035)')
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,first_name,name,telephone) VALUES (104, 1, \'Eagan\', \'Hutchinson\', 93829462)')
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,first_name,name,telephone) VALUES (108, 1, \'Rahim\', \'Wilson\', 14499323)')
+        self.conn.commit()
+        Controller().configure().execute()
+        self.cursor.execute('SELECT * FROM user ORDER BY foreign_id ASC')
+        for fetched_data_set in self.cursor:
+            self.assertEqual(fetched_data_set, expected_result.pop(0))
\ No newline at end of file
diff --git a/hshetl/test/functional/test_hshetl.py b/hshetl/test/functional/test_hshetl.py
deleted file mode 100644
index 6213df9a7f8a754b509cf4327017c3e1764f7a66..0000000000000000000000000000000000000000
--- a/hshetl/test/functional/test_hshetl.py
+++ /dev/null
@@ -1,196 +0,0 @@
-import unittest
-import sys
-import os
-import sqlite3
-import shutil
-import filecmp
-from hshetl.cli import Controller
-
-class TestSyncFileToSQLiteSync(unittest.TestCase):
-
-    def setUp(self):
-        self.current_dir = os.getcwd()
-        self.fixture_dir = os.path.dirname(__file__) + '/../../../docs/examples/file2sqlitesync/'
-        self.test_dir = '/tmp/hshetl_test/'
-        self.test_working_directory = '/tmp/hshetl_test/file2sqlitesync/'
-        os.makedirs(self.test_dir)
-        shutil.copytree(self.fixture_dir, self.test_working_directory)
-        self.conn = sqlite3.connect(self.test_working_directory + 'person.sqlite3')
-        self.cursor = self.conn.cursor()
-        self.cursor.execute('CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR(50), inactive BOOL, foreign_id INT, telephone INT);')
-        self.conn.commit()
-        sys.argv = ['hshetl', '-d', self.test_working_directory]
-
-    def tearDown(self):
-        os.chdir(self.current_dir)
-        self.conn.close()
-        shutil.rmtree(self.test_dir)
-
-
-    def test_batch_run_inserts_right_amount_of_data_sets(self):
-        Controller().configure().execute()
-        self.cursor.execute('SELECT * FROM user')
-        data_set_count = 0
-        for _ in self.cursor:
-            data_set_count += 1
-        self.assertEqual(data_set_count, 100, 'The database does contain ' + str(data_set_count) + ' data sets instead of the expected 100.')
-
-    def test_sync_inserts_missing_data_set(self):
-        csv_file = open(self.test_working_directory + '/data/person.csv', 'w')
-        csv_file.write('p_num,name,retired,telephone\n100,Hanae Ferguson,1,67466035')
-        csv_file.close()
-        Controller().configure().execute()
-        self.cursor.execute('SELECT * FROM user')
-        self.assertEqual(self.cursor.fetchone(), (1, u'Hanae Ferguson', 1, 100, 67466035))
-
-    def test_sync_updates_outdated_data_set(self):
-        csv_file = open(self.test_working_directory + 'data/person.csv', 'w')
-        csv_file.write('p_num,name,retired,telephone\n100,Hanna Ferguson,0,12345678')
-        csv_file.close()
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone,id) VALUES(100, 1, \'Hanae Ferguson\', 67466035,20)')
-        self.conn.commit()
-        Controller().configure().execute()
-        self.cursor.execute('SELECT * FROM user')
-        self.assertEqual(self.cursor.fetchone(), (20, u'Hanna Ferguson', 0, 100, 12345678))
-
-    def test_sync_deletes_outdated_data_set(self):
-        csv_file = open(self.test_working_directory + 'data/person.csv', 'w')
-        csv_file.write('p_num,name,retired,telephone\n')
-        csv_file.close()
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone,id) VALUES(100, 1, \'Hanae Ferguson\', 67466035,20)')
-        self.conn.commit()
-        Controller().configure().execute()
-        self.cursor.execute('SELECT * FROM user')
-        self.assertEqual(self.cursor.fetchone(), None, 'A data set that does not exist in the source system was not deleted.')
-
-
-
-    def test_sync_handles_insert_update_and_delete_simultaneously(self):
-        expected_result = [(1, u'Hanae Ferguson', 1, 100, 67466035),
-                           (2, u'Rowan Garrison', 1, 102, 39447759),
-                           (4, u'Rahim Wilson', 1, 108, 14499323),
-                           (5, u'David Franks', 1, 106, 70673167)]
-        csv_file = open(self.test_working_directory + 'data/person.csv', 'w')
-        csv_file.write('p_num,name,retired,telephone\n100,Hanae Ferguson,1,67466035\n102,Rowan Garrison,1,39447759\n106,David Franks,1,70673167\n108,Rahim Wilson,1,14499323\n')
-        csv_file.close()
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone) VALUES(100, 1, \'Hanae Ferguson\', 12345678)')
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone) VALUES(102, 0, \'Garry Garrison\', 67466035)')
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone) VALUES(104, 1, \'Eagan Hutchinson\', 93829462)')
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone) VALUES(108, 1, \'Rahim Wilson\', 14499323)')
-        self.conn.commit()
-        Controller().configure().execute()
-        self.cursor.execute('SELECT * FROM user ORDER BY id ASC')
-        for fetched_data_set in self.cursor:
-            self.assertEqual(fetched_data_set, expected_result.pop(0))
-
-
-class TestFileToSQLiteWithMultipleIdentifiers(unittest.TestCase):
-
-    def setUp(self):
-        self.current_dir = os.getcwd()
-        self.fixture_dir = os.path.dirname(__file__) + '/../../../docs/examples/file2sqlitemultipleidentifiers/'
-        self.test_dir = '/tmp/hshetl_test/'
-        self.test_working_directory = '/tmp/hshetl_test/file2sqlitemultipleidentifiers/'
-        os.makedirs(self.test_dir)
-        shutil.copytree(self.fixture_dir, self.test_working_directory)
-        self.conn = sqlite3.connect(self.test_working_directory + 'person.sqlite3')
-        self.cursor = self.conn.cursor()
-        self.cursor.execute('CREATE TABLE user (name VARCHAR(50), first_name VARCHAR(255), inactive BOOL, foreign_id INT, telephone INT);')
-        self.conn.commit()
-        sys.argv = ['hshetl', '-d', self.test_working_directory]
-
-    def tearDown(self):
-        os.chdir(self.current_dir)
-        self.conn.close()
-        shutil.rmtree(self.test_dir)
-
-
-    def test_sync_handles_insert_update_and_delete_simultaneously(self):
-        expected_result = [(u'Mueller', u'Hannah', 1, 100, 67466035),
-                           (u'Mueller', u'Robert', 1, 102, 39447759),
-                           (u'Meier', u'David', 1, 106, 70673167),
-                           (u'Meier', u'Ingrid', 1, 108, 14499323),
-                           (u'Mustermann', u'Max', 0, 110, 12345567)]
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,first_name,name,telephone) VALUES (100, 0, \'Hannah\', \'Mueller\', 12345678)')
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,first_name,name,telephone) VALUES (100, 0, \'Robert\', \'Mueller\', 67466035)')
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,first_name,name,telephone) VALUES (104, 1, \'Eagan\', \'Hutchinson\', 93829462)')
-        self.cursor.execute('INSERT INTO user (foreign_id,inactive,first_name,name,telephone) VALUES (108, 1, \'Rahim\', \'Wilson\', 14499323)')
-        self.conn.commit()
-        Controller().configure().execute()
-        self.cursor.execute('SELECT * FROM user ORDER BY foreign_id ASC')
-        for fetched_data_set in self.cursor:
-            self.assertEqual(fetched_data_set, expected_result.pop(0))
-
-
-class TestSqlQueryJob(unittest.TestCase):
-
-    def setUp(self):
-        self.current_dir = os.getcwd()
-        self.fixture_dir = os.path.dirname(__file__) + '/../../../docs/examples/sqlquery/'
-        self.test_dir = '/tmp/hshetl_test/'
-        self.test_working_directory = '/tmp/hshetl_test/sqlquery/'
-        os.makedirs(self.test_dir)
-        shutil.copytree(self.fixture_dir, self.test_working_directory)
-        self.conn = sqlite3.connect(self.test_working_directory + 'person.sqlite3')
-        self.cursor = self.conn.cursor()
-        sys.argv = ['hshetl', '-d', self.test_working_directory]
-
-    def tearDown(self):
-        os.chdir(self.current_dir)
-        self.conn.close()
-        shutil.rmtree(self.test_dir)
-
-
-    def test_job_creates_table_and_inserts_data_as_configured(self):
-        Controller().configure().execute()
-        self.cursor.execute('SELECT * FROM user')
-        for result in self.cursor:
-            pass
-        expected_result = (1, u'Max', 0, 42, 12345678)
-        self.assertEqual(expected_result, result, 'The sqlite3 db does not contain the results from the job query.')
-
-
-class TestFakerCopyJob(unittest.TestCase):
-
-    def setUp(self):
-        self.current_dir = os.getcwd()
-        self.fixture_dir = os.path.dirname(__file__) + '/../../../docs/examples/faker2filecopy/'
-        self.test_dir = '/tmp/hshetl_test/'
-        self.test_working_directory = '/tmp/hshetl_test/faker2filecopy/'
-        os.makedirs(self.test_dir)
-        shutil.copytree(self.fixture_dir, self.test_working_directory)
-        sys.argv = ['hshetl', '-d', self.test_working_directory]
-
-    def tearDown(self):
-        os.chdir(self.current_dir)
-        shutil.rmtree(self.test_dir)
-
-
-    def test_job(self):
-        Controller().configure().execute()
-        self.assertTrue(filecmp.cmp(self.test_working_directory + 'data/expected_fakeperson.csv', self.test_working_directory + 'fakeperson.csv'))
-
-
-class TestCopyJob(unittest.TestCase):
-
-    def setUp(self):
-        self.current_dir = os.getcwd()
-        self.fixture_dir = os.path.dirname(__file__) + '/../../../docs/examples/sqlite2filecopy/'
-        self.test_dir = '/tmp/hshetl_test/'
-        self.test_working_directory = '/tmp/hshetl_test/sqlite2filecopy/'
-        os.makedirs(self.test_dir)
-        shutil.copytree(self.fixture_dir, self.test_working_directory)
-        sys.argv = ['hshetl', '-d', self.test_working_directory]
-
-    def tearDown(self):
-        os.chdir(self.current_dir)
-        shutil.rmtree(self.test_dir)
-
-
-    def test_job(self):
-        Controller().configure().execute()
-        self.assertTrue(filecmp.cmp(self.test_working_directory + 'data/expected_person.csv', self.test_working_directory + 'person.csv'))
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/hshetl/test/functional/test_query_sqlquery2sqlite.py b/hshetl/test/functional/test_query_sqlquery2sqlite.py
new file mode 100644
index 0000000000000000000000000000000000000000..a3262a381110159827303194f5259472f41994d5
--- /dev/null
+++ b/hshetl/test/functional/test_query_sqlquery2sqlite.py
@@ -0,0 +1,27 @@
+from hshetl.test.functional import TestBaseClass
+from hshetl.cli import Controller
+import sys
+import sqlite3
+
+class TestSqlQueryJob(TestBaseClass):
+
+    example_dir_name = 'query_sqlquery2sqlite'
+
+    def setUp(self):
+        super(TestSqlQueryJob, self).setUp()
+        self.conn = sqlite3.connect(self.test_working_directory + 'person.sqlite3')
+        self.cursor = self.conn.cursor()
+        sys.argv = ['hshetl', '-d', self.test_working_directory]
+
+    def tearDown(self):
+        super(TestSqlQueryJob, self).tearDown()
+        self.conn.close()
+
+
+    def test_job_creates_table_and_inserts_data_as_configured(self):
+        Controller().configure().execute()
+        self.cursor.execute('SELECT * FROM user')
+        for result in self.cursor:
+            pass
+        expected_result = (1, u'Max', 0, 42, 12345678)
+        self.assertEqual(expected_result, result, 'The sqlite3 db does not contain the results from the job query.')
\ No newline at end of file
diff --git a/hshetl/test/functional/test_sync_file2sqlite.py b/hshetl/test/functional/test_sync_file2sqlite.py
new file mode 100644
index 0000000000000000000000000000000000000000..40cba1abfde3c91a1df33503a804ceb4084efd95
--- /dev/null
+++ b/hshetl/test/functional/test_sync_file2sqlite.py
@@ -0,0 +1,75 @@
+from hshetl.test.functional import TestBaseClass
+from hshetl.cli import Controller
+import sys
+import sqlite3
+
+class TestSyncFileToSQLiteSync(TestBaseClass):
+
+    example_dir_name = 'sync_file2sqlite'
+
+    def setUp(self):
+        super(TestSyncFileToSQLiteSync, self).setUp()
+        self.conn = sqlite3.connect(self.test_working_directory + 'person.sqlite3')
+        self.cursor = self.conn.cursor()
+        self.cursor.execute('CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR(50), inactive BOOL, foreign_id INT, telephone INT);')
+        self.conn.commit()
+        sys.argv = ['hshetl', '-d', self.test_working_directory]
+
+    def tearDown(self):
+        super(TestSyncFileToSQLiteSync, self).tearDown()
+        self.conn.close()
+
+
+    def test_batch_run_inserts_right_amount_of_data_sets(self):
+        Controller().configure().execute()
+        self.cursor.execute('SELECT * FROM user')
+        data_set_count = 0
+        for _ in self.cursor:
+            data_set_count += 1
+        self.assertEqual(data_set_count, 100, 'The database does contain ' + str(data_set_count) + ' data sets instead of the expected 100.')
+
+    def test_sync_inserts_missing_data_set(self):
+        csv_file = open(self.test_working_directory + '/data/person.csv', 'w')
+        csv_file.write('p_num,name,retired,telephone\n100,Hanae Ferguson,1,67466035')
+        csv_file.close()
+        Controller().configure().execute()
+        self.cursor.execute('SELECT * FROM user')
+        self.assertEqual(self.cursor.fetchone(), (1, u'Hanae Ferguson', 1, 100, 67466035))
+
+    def test_sync_updates_outdated_data_set(self):
+        csv_file = open(self.test_working_directory + 'data/person.csv', 'w')
+        csv_file.write('p_num,name,retired,telephone\n100,Hanna Ferguson,0,12345678')
+        csv_file.close()
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone,id) VALUES(100, 1, \'Hanae Ferguson\', 67466035,20)')
+        self.conn.commit()
+        Controller().configure().execute()
+        self.cursor.execute('SELECT * FROM user')
+        self.assertEqual(self.cursor.fetchone(), (20, u'Hanna Ferguson', 0, 100, 12345678))
+
+    def test_sync_deletes_outdated_data_set(self):
+        csv_file = open(self.test_working_directory + 'data/person.csv', 'w')
+        csv_file.write('p_num,name,retired,telephone\n')
+        csv_file.close()
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone,id) VALUES(100, 1, \'Hanae Ferguson\', 67466035,20)')
+        self.conn.commit()
+        Controller().configure().execute()
+        self.cursor.execute('SELECT * FROM user')
+        self.assertEqual(self.cursor.fetchone(), None, 'A data set that does not exist in the source system was not deleted.')
+
+    def test_sync_handles_insert_update_and_delete_simultaneously(self):
+        expected_result = [(1, u'Hanae Ferguson', 1, 100, 67466035),
+                           (2, u'Rowan Garrison', 1, 102, 39447759),
+                           (4, u'Rahim Wilson', 1, 108, 14499323),
+                           (5, u'David Franks', 1, 106, 70673167)]
+        csv_file = open(self.test_working_directory + 'data/person.csv', 'w')
+        csv_file.write('p_num,name,retired,telephone\n100,Hanae Ferguson,1,67466035\n102,Rowan Garrison,1,39447759\n106,David Franks,1,70673167\n108,Rahim Wilson,1,14499323\n')
+        csv_file.close()
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone) VALUES(100, 1, \'Hanae Ferguson\', 12345678)')
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone) VALUES(102, 0, \'Garry Garrison\', 67466035)')
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone) VALUES(104, 1, \'Eagan Hutchinson\', 93829462)')
+        self.cursor.execute('INSERT INTO user (foreign_id,inactive,name,telephone) VALUES(108, 1, \'Rahim Wilson\', 14499323)')
+        self.conn.commit()
+        Controller().configure().execute()
+        self.cursor.execute('SELECT * FROM user ORDER BY id ASC')
+        for fetched_data_set in self.cursor:
+            self.assertEqual(fetched_data_set, expected_result.pop(0))