diff --git a/.gitignore b/.gitignore
index e0934d5bb8aa607ffdb9744cea0969892cf32c5c..381cefd92ae437b42901b9272a597a3d12156320 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,8 @@ appointment-import/tmp.sql
 *.iml
 out
 .idea
+
+#coverage tool
+.coverage
+smash/htmlcov/*
+
diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py
index 4adab0a0359062730e5d801833ce0a2ddae4fe3d..cd6915a53a3f6a41227f2bb34fdcddc6f8fd4607 100644
--- a/smash/web/tests/functions.py
+++ b/smash/web/tests/functions.py
@@ -38,11 +38,15 @@ def create_subject():
         country="france")
 
 
-def create_user():
+def create_user(username=None, password=None):
+    if username is None:
+        username = 'piotr'
+    if password is None:
+        password = 'top_secret'
     user = User.objects.create_user(
-        username='piotr',
+        username=username,
         email='jacob@bla',
-        password='top_secret')
+        password=password)
 
     create_worker(user)
     return user
diff --git a/smash/web/tests/test_view_notifications.py b/smash/web/tests/test_view_notifications.py
index 435027842e8c2a92b38e2489c7f70830a91e43f3..817ec07cb60733cefdd4b41da16c009d3c16d06f 100644
--- a/smash/web/tests/test_view_notifications.py
+++ b/smash/web/tests/test_view_notifications.py
@@ -13,13 +13,15 @@ from web.views.notifications import \
     get_approaching_visits_without_appointments, \
     get_approaching_visits_without_appointments_count, \
     get_exceeded_visit_notifications_count, \
+    get_notifications, \
     get_subject_with_no_visit_notifications_count, \
     get_subjects_with_reminder_count, \
     get_visits_without_appointments_count, \
+    get_visits_with_missing_appointments_count, \
     get_today_midnight_date, \
     get_unfinished_appointments, \
     get_unfinished_appointments_count, \
-    get_unfinished_visits
+    get_unfinished_visits, get_active_visits_with_missing_appointments
 
 
 class NotificationViewTests(TestCase):
@@ -62,6 +64,41 @@ class NotificationViewTests(TestCase):
         notification = get_visits_without_appointments_count(self.user)
         self.assertEquals(original_notification.count + 1, notification.count)
 
+    def test_get_visits_with_missing_appointments_count(self):
+        original_notification = get_visits_with_missing_appointments_count(self.user)
+
+        appointment_type = create_appointment_type()
+        visit = create_visit()
+        visit.appointment_types.add(appointment_type)
+        visit.save()
+
+        notification = get_visits_with_missing_appointments_count(self.user)
+        self.assertEquals(original_notification.count + 1, notification.count)
+
+    def test_get_visits_with_missing_appointments_count_2(self):
+        original_notification = get_visits_with_missing_appointments_count(self.user)
+
+        appointment_type = create_appointment_type()
+        visit = create_visit()
+        visit.appointment_types.add(appointment_type)
+        visit.save()
+
+        appointment = create_appointment(visit)
+        appointment.appointment_types.add(appointment_type)
+        appointment.status=Appointment.APPOINTMENT_STATUS_FINISHED
+        appointment.save()
+
+        notification = get_visits_with_missing_appointments_count(self.user)
+        self.assertEquals(original_notification.count, notification.count)
+
+    def test_get_notifications(self):
+        create_worker(self.user)
+        result = get_notifications(self.user)
+
+        self.assertEquals(0, result[0])
+        self.assertTrue(isinstance(result[1], list))
+        self.assertTrue(len(result[1]) > 0)
+
     def test_get_visits_without_appointments_count_2(self):
         appointment_type = create_appointment_type()
         original_notification = get_visits_without_appointments_count(self.user)
diff --git a/smash/web/tests/test_view_subjects.py b/smash/web/tests/test_view_subjects.py
index 596cd3104f8ec56e5854fb0f15a58f12284e316b..39783854007eceecff55a6d76a5205d7f258aad1 100644
--- a/smash/web/tests/test_view_subjects.py
+++ b/smash/web/tests/test_view_subjects.py
@@ -1,12 +1,15 @@
+import datetime
+
 from django.contrib.auth.models import User
 from django.test import Client
 from django.test import TestCase
 from django.urls import reverse
 
-from functions import create_subject, create_worker, get_test_location
-from web.forms import SubjectAddForm
+from functions import create_subject, create_visit, create_appointment, create_worker, get_test_location
+from web.forms import SubjectAddForm, SubjectEditForm
 from web.models import Subject
 from web.models.constants import SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL
+from web.views.notifications import get_today_midnight_date
 
 
 class SubjectsViewTests(TestCase):
@@ -30,11 +33,43 @@ class SubjectsViewTests(TestCase):
         # check if screening number prefix is there
         self.assertTrue("value=\"X-\"" in response.content)
 
+    def test_render_subject_edit(self):
+        subject = create_subject()
+
+        response = self.client.get(reverse('web.views.subject_edit', kwargs={'id': subject.id}))
+        self.assertEqual(response.status_code, 200)
+
+    def test_render_subject_visit_details(self):
+        subject = create_subject()
+        visit = create_visit(subject)
+        appointment = create_appointment(visit)
+
+        response = self.client.get(reverse('web.views.subject_visit_details', kwargs={'id': subject.id}))
+        self.assertEqual(response.status_code, 200)
+
+    def test_save_subject_edit(self):
+        subject = create_subject()
+        form_subject = SubjectEditForm(instance=subject)
+        form_data = {}
+        for key, value in form_subject.initial.items():
+            if value is not None:
+                form_data[key] = value
+
+        form_data['dead'] = "True"
+        form_data['resigned'] = "True"
+        response = self.client.post(
+            reverse('web.views.subject_edit', kwargs={'id': subject.id}), data=form_data)
+
+        self.assertEqual(response.status_code, 302)
+        updated_subject = Subject.objects.filter(id=subject.id)[0]
+        self.assertTrue(updated_subject.dead)
+        self.assertTrue(updated_subject.resigned)
+
     def test_subjects_add_2(self):
         self.worker.screening_number_prefix = "X"
         self.worker.save()
 
-        form = SubjectAddForm(user= self.user)
+        form = SubjectAddForm(user=self.user)
         form_data = {}
         for key, value in form.initial.items():
             if value is not None:
@@ -51,6 +86,23 @@ class SubjectsViewTests(TestCase):
         self.assertEqual(response.status_code, 302)
 
         subject = Subject.objects.all()[0]
-        self.assertEqual("X-001",subject.screening_number)
+        self.assertEqual("X-001", subject.screening_number)
+
+    def test_render_subjects(self):
+        create_subject()
+
+        response = self.client.get(reverse('web.views.subjects'))
+        self.assertEqual(response.status_code, 200)
+
+    def test_render_subjects_with_no_visit(self):
+        create_subject()
 
+        response = self.client.get(reverse('web.views.subject_no_visits'))
+        self.assertEqual(response.status_code, 200)
 
+    def test_render_subjects_require_contact(self):
+        subject = create_subject()
+        subject.datetime_contact_reminder = get_today_midnight_date() + datetime.timedelta(days=-1)
+
+        response = self.client.get(reverse('web.views.subject_require_contact'))
+        self.assertEqual(response.status_code, 200)
diff --git a/smash/web/tests/test_view_visit.py b/smash/web/tests/test_view_visit.py
index e1979cea43307c6793cc2685ee0f99146170264b..21c16290d0c03e4a68b4d60c52c9be11bfaf8144 100644
--- a/smash/web/tests/test_view_visit.py
+++ b/smash/web/tests/test_view_visit.py
@@ -1,24 +1,138 @@
-from django.contrib.auth.models import User
-from django.test import TestCase, RequestFactory
+import datetime
+
+from django.test import Client
+from django.test import TestCase
 from django.urls import reverse
 
-from functions import create_subject, create_visit, create_appointment
-from web.views.visit import visit_details
+from functions import \
+    create_appointment, \
+    create_appointment_type, \
+    create_subject, \
+    create_visit, \
+    create_user
+from web.forms import VisitDetailForm, VisitAddForm
+from web.models import Subject, Visit
+from web.views.notifications import get_today_midnight_date
 
 
 class VisitViewTests(TestCase):
     def setUp(self):
-        # Every test needs access to the request factory.
-        self.factory = RequestFactory()
-        self.user = User.objects.create_user(
-            username='piotr', email='jacob@bla', password='top_secret')
+        username = 'piotr'
+        password = 'top_secret'
+
+        self.client = Client()
+        self.user = create_user(username, password)
+        self.client.login(username=username, password=password)
 
     def test_visit_details_request(self):
-        subject = create_subject()
-        visit = create_visit(subject)
+        visit = create_visit()
         create_appointment(visit)
 
-        request = self.factory.get(reverse('web.views.visit_details', args=[visit.id]))
-        request.user = self.user
-        response = visit_details(request, visit.id)
+        response = self.client.get(reverse('web.views.visit_details', args=[visit.id]))
+        self.assertEqual(response.status_code, 200)
+
+    def test_save_visit_details(self):
+        visit = create_visit()
+        create_appointment(visit)
+
+        form_appointment = VisitDetailForm(instance=visit)
+        form_data = {}
+        for key, value in form_appointment.initial.items():
+            if value is not None:
+                if isinstance(value, datetime.datetime):
+                    form_data[key] = value.strftime("%Y-%m-%d")
+                else:
+                    form_data[key] = value
+
+        response = self.client.post(
+            reverse('web.views.visit_details', kwargs={'id': visit.id}), data=form_data)
+        self.assertEqual(response.status_code, 200)
+        self.assertFalse("error" in response.content)
+
+    def test_render_add_visit(self):
+        subject = create_subject()
+
+        response = self.client.get(reverse('web.views.visit_add', kwargs={'subject_id': subject.id}))
+        self.assertEqual(response.status_code, 200)
+
+    def test_save_add_visit(self):
+        visit_count = Visit.objects.all().count()
+        subject = create_subject()
+
+        form = VisitAddForm()
+        form_data = {}
+        for key, value in form.initial.items():
+            if value is not None:
+                if isinstance(value, datetime.datetime):
+                    form_data[key] = value.strftime("%Y-%m-%d")
+                else:
+                    form_data[key] = value
+
+        form_data["datetime_begin"] = "2017-01-01"
+        form_data["datetime_end"] = "2017-04-01"
+        form_data["subject"] = subject.id
+
+        response = self.client.post(reverse('web.views.visit_add', kwargs={'subject_id': subject.id}), data=form_data)
+        self.assertEqual(response.status_code, 302)
+        self.assertFalse("error" in response.content)
+
+        visit_count_new = Visit.objects.all().count()
+
+        self.assertEqual(visit_count + 1, visit_count_new)
+
+    def test_mark_as_finished(self):
+        visit = create_visit()
+
+        self.assertFalse(visit.is_finished)
+
+        response = self.client.get(reverse('web.views.visit_mark', args=[visit.id, "finished"]))
+        self.assertEqual(response.status_code, 302)
+
+        new_visit = Visit.objects.get(id=visit.id)
+        self.assertTrue(new_visit.is_finished)
+
+    def test_visit_list(self):
+        create_visit()
+
+        response = self.client.get(reverse('web.views.visits'))
+        self.assertEqual(response.status_code, 200)
+
+    def test_visit_with_missing_appointment_list(self):
+        visit = create_visit()
+        visit.appointment_types.add(create_appointment_type())
+        visit.save()
+
+        response = self.client.get(reverse('web.views.visits_with_missing_appointments'))
+        self.assertEqual(response.status_code, 200)
+
+    def test_approaching_visits_without_appointments(self):
+        visit = create_visit()
+        visit.datetime_begin = get_today_midnight_date() + datetime.timedelta(days=2)
+        visit.save()
+
+        response = self.client.get(reverse("web.views.approaching_visits_without_appointments"))
+        self.assertEqual(response.status_code, 200)
+
+    def test_approaching_visits_for_mail_contact(self):
+        visit = create_visit()
+        visit.datetime_begin = get_today_midnight_date() + datetime.timedelta(days=100)
+        visit.save()
+
+        response = self.client.get(reverse("web.views.approaching_visits_for_mail_contact"))
+        self.assertEqual(response.status_code, 200)
+
+    def test_exceeded_visits(self):
+        visit = create_visit()
+        visit.datetime_end = "2011-01-01"
+        visit.save()
+
+        response = self.client.get(reverse("web.views.exceeded_visits"))
+        self.assertEqual(response.status_code, 200)
+
+    def test_unfinished_visits(self):
+        visit = create_visit()
+        visit.datetime_begin = get_today_midnight_date() + datetime.timedelta(days=-10)
+        visit.save()
+
+        response = self.client.get(reverse("web.views.unfinished_visits"))
         self.assertEqual(response.status_code, 200)
diff --git a/smash/web/urls.py b/smash/web/urls.py
index a2c7a7ba48b0fe07037a8bfb4e73ae6d40adebc9..6bfa4151411ba8b0711be7ade684a21885d91b36 100644
--- a/smash/web/urls.py
+++ b/smash/web/urls.py
@@ -50,7 +50,6 @@ urlpatterns = [
     url(r'^subjects/subject_visit_details/(?P<id>\d+)$', views.subject.subject_visit_details,
         name='web.views.subject_visit_details'),
     url(r'^subjects/edit/(?P<id>\d+)$', views.subject.subject_edit, name='web.views.subject_edit'),
-    url(r'^subjects/delete/(?P<id>\d+)$', views.subject.subject_delete, name='web.views.subject_delete'),
 
     url(r'^doctors$', views.doctor.doctors, name='web.views.doctors'),
     url(r'^doctors/add$', views.doctor.doctor_add, name='web.views.doctor_add'),
diff --git a/smash/web/views/notifications.py b/smash/web/views/notifications.py
index ce900ae8f6fae4bac90c3da8a4b5d9bca141838e..0c57e769614b0c18076a4bc6079520af0a4ed79d 100644
--- a/smash/web/views/notifications.py
+++ b/smash/web/views/notifications.py
@@ -92,23 +92,21 @@ def get_unfinished_appointments_count(user):
 
 
 def get_notifications(the_user):
-    workers = Worker.objects.filter(user=the_user)
+    worker = Worker.get_by_user(the_user)
     notifications = []
     count = 0
-    if len(workers) > 0:
-        person = workers[0]
-        if person.role == Worker.ROLE_CHOICES_SECRETARY:
-            notifications.append(get_exceeded_visit_notifications_count(person))
-            notifications.append(get_visits_without_appointments_count(person))
-            notifications.append(get_approaching_visits_without_appointments_count(person))
-            notifications.append(get_unfinished_appointments_count(person))
-            notifications.append(get_visits_with_missing_appointments_count(person))
-            notifications.append(get_subject_with_no_visit_notifications_count(person))
-            notifications.append(get_approaching_visits_for_mail_contact_count(person))
-            notifications.append(get_subjects_with_reminder_count(person))
-
-            for notification in notifications:
-                count += notification.count
+    if worker is not None:
+        notifications.append(get_exceeded_visit_notifications_count(worker))
+        notifications.append(get_visits_without_appointments_count(worker))
+        notifications.append(get_approaching_visits_without_appointments_count(worker))
+        notifications.append(get_unfinished_appointments_count(worker))
+        notifications.append(get_visits_with_missing_appointments_count(worker))
+        notifications.append(get_subject_with_no_visit_notifications_count(worker))
+        notifications.append(get_approaching_visits_for_mail_contact_count(worker))
+        notifications.append(get_subjects_with_reminder_count(worker))
+
+        for notification in notifications:
+            count += notification.count
     return count, notifications
 
 
diff --git a/smash/web/views/subject.py b/smash/web/views/subject.py
index ae3599b42641a7b73e32e7b9d98c54f0a57bb6c6..37732d54a789e0ca7dd86a0b27273ea299b8f6ad 100644
--- a/smash/web/views/subject.py
+++ b/smash/web/views/subject.py
@@ -72,26 +72,16 @@ def subject_edit(request, id):
     })
 
 
-def subject_delete(request, id):
-    the_subject = get_object_or_404(Subject, id=id)
-    if request.method == 'POST':
-        the_subject.delete()
-        return redirect('web.views.subjects')
-    else:
-        form = SubjectEditForm(instance=the_subject)
-    return wrap_response(request, 'subjects/delete.html', {'form': form})
-
-
 def subject_visit_details(request, id):
-    locsubject = get_object_or_404(Subject, id=id)
-    visits = locsubject.visit_set.all()
-    endlist = []
-    for vis in visits:
-        assign = vis.appointment_set.all()
-        finished = vis.is_finished
-        visid = vis.id
-        visit_title = vis.follow_up_title()
-        visform = VisitDetailForm(instance=vis)
-        endlist.append((visform, assign, finished, visid, visit_title))
-
-    return wrap_response(request, 'subjects/visitdetails.html', {'display': endlist, "id": id})
+    subjects = get_object_or_404(Subject, id=id)
+    visits = subjects.visit_set.all()
+    visits_data = []
+    for visit in visits:
+        appointments = visit.appointment_set.all()
+        finished = visit.is_finished
+        visit_id = visit.id
+        visit_title = visit.follow_up_title()
+        visit_form = VisitDetailForm(instance=visit)
+        visits_data.append((visit_form, appointments, finished, visit_id, visit_title))
+
+    return wrap_response(request, 'subjects/visitdetails.html', {'display': visits_data, "id": id})