From c63350c05d1a956164507f0ff8d9409a7d13e7ea Mon Sep 17 00:00:00 2001 From: Aviliani Pramestya Date: Wed, 16 Oct 2019 12:33:56 +0700 Subject: [PATCH 1/7] commit to heroku --- lists/templates/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lists/templates/base.html b/lists/templates/base.html index 2bf1850..87296be 100644 --- a/lists/templates/base.html +++ b/lists/templates/base.html @@ -56,4 +56,4 @@ - \ No newline at end of file + -- GitLab From 5fd443cc864f1385357110189db8742395f3f66d Mon Sep 17 00:00:00 2001 From: Aviliani Pramestya Date: Thu, 7 Nov 2019 16:37:27 +0700 Subject: [PATCH 2/7] add first mutant --- lists/templates/list.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lists/templates/list.html b/lists/templates/list.html index df0238f..e986dac 100644 --- a/lists/templates/list.html +++ b/lists/templates/list.html @@ -14,7 +14,8 @@ {% block comment %}
- {% if list.item_set.all.count >= 5 %} + + {% if list.item_set.all.count < 5 %}

OH TIDAKKK

{% elif list.item_set.all.count >= 1 %}

sibuk tapi santai

-- GitLab From 6c85f14367222a6e4e3f0cbd5a2616902920288a Mon Sep 17 00:00:00 2001 From: Aviliani Pramestya Date: Thu, 7 Nov 2019 16:44:07 +0700 Subject: [PATCH 3/7] add second mutant --- lists/templates/list.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lists/templates/list.html b/lists/templates/list.html index e986dac..5e42a65 100644 --- a/lists/templates/list.html +++ b/lists/templates/list.html @@ -14,10 +14,9 @@ {% block comment %}
- - {% if list.item_set.all.count < 5 %} + {% if list.item_set.all.count >= 5 %}

OH TIDAKKK

- {% elif list.item_set.all.count >= 1 %} + {% elif list.item_set.all.count == 1 %}

sibuk tapi santai

{% else %}

yey, waktunya berlibur

-- GitLab From 4860a76ead0904fd498ab0e1ed898063fc193bbe Mon Sep 17 00:00:00 2001 From: Aviliani Pramestya Date: Thu, 7 Nov 2019 17:06:03 +0700 Subject: [PATCH 4/7] edit test view --- lists/templates/list.html | 2 +- lists/tests/test_views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lists/templates/list.html b/lists/templates/list.html index 5e42a65..df0238f 100644 --- a/lists/templates/list.html +++ b/lists/templates/list.html @@ -16,7 +16,7 @@
{% if list.item_set.all.count >= 5 %}

OH TIDAKKK

- {% elif list.item_set.all.count == 1 %} + {% elif list.item_set.all.count >= 1 %}

sibuk tapi santai

{% else %}

yey, waktunya berlibur

diff --git a/lists/tests/test_views.py b/lists/tests/test_views.py index ee50262..b68b595 100644 --- a/lists/tests/test_views.py +++ b/lists/tests/test_views.py @@ -19,7 +19,7 @@ class HomePageTest(TestCase): html = response.content.decode('utf8') self.assertTrue(html.startswith('')) self.assertIn('Aviliani\'s Homepage', html) - self.assertTrue(html.endswith('')) + self.assertTrue(html.strip().endswith('')) def test_uses_home_template(self): response = self.client.get('/') -- GitLab From 2b19100314c9880d55b0d9fc6836684749ce331f Mon Sep 17 00:00:00 2001 From: Aviliani Pramestya Date: Thu, 7 Nov 2019 17:16:06 +0700 Subject: [PATCH 5/7] add django_mutpy in settings and requirements --- requirements.txt | 9 +++++++++ superlists/settings.py | 1 + 2 files changed, 10 insertions(+) diff --git a/requirements.txt b/requirements.txt index b2c9fc6..e037726 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,17 @@ +astmonkey==0.3.6 dj-database-url==0.5.0 Django==1.11.24 +django-mutpy==0.1.2 gunicorn==19.9.0 +Jinja2==2.10.3 +MarkupSafe==1.1.1 +MutPy==0.6.0 psycopg2==2.8.3 +pydot==1.4.1 +pyparsing==2.4.4 pytz==2019.2 +PyYAML==5.1.2 selenium==3.141.0 +termcolor==1.1.0 urllib3==1.25.3 whitenoise==4.1.3 diff --git a/superlists/settings.py b/superlists/settings.py index b28ce15..736f5e2 100644 --- a/superlists/settings.py +++ b/superlists/settings.py @@ -38,6 +38,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django_mutpy', 'lists', ] -- GitLab From 86652fdd7321192c9246e7f08368e49546999b87 Mon Sep 17 00:00:00 2001 From: Aviliani Pramestya Date: Thu, 7 Nov 2019 17:33:48 +0700 Subject: [PATCH 6/7] move function from html to views.py --- lists/templates/list.html | 8 +------- lists/tests/test_views.py | 42 +++++++++++++++++++++++++++++---------- lists/views.py | 10 +++++++++- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/lists/templates/list.html b/lists/templates/list.html index df0238f..27076ab 100644 --- a/lists/templates/list.html +++ b/lists/templates/list.html @@ -14,12 +14,6 @@ {% block comment %}
- {% if list.item_set.all.count >= 5 %} -

OH TIDAKKK

- {% elif list.item_set.all.count >= 1 %} -

sibuk tapi santai

- {% else %} -

yey, waktunya berlibur

- {% endif %} + {{ comment }}
{% endblock %} \ No newline at end of file diff --git a/lists/tests/test_views.py b/lists/tests/test_views.py index b68b595..8a062ad 100644 --- a/lists/tests/test_views.py +++ b/lists/tests/test_views.py @@ -25,18 +25,38 @@ class HomePageTest(TestCase): response = self.client.get('/') self.assertTemplateUsed(response, 'index.html') - def test_displays_automated_comment(self): - cases = [ - (0, "yey, waktunya berlibur"), - (1, "sibuk tapi santai"), - (4, "OH TIDAKKK") - ] + # def test_displays_automated_comment(self): + # cases = [ + # (0, "yey, waktunya berlibur"), + # (1, "sibuk tapi santai"), + # (4, "OH TIDAKKK") + # ] + # list_ = List.objects.create() + # for n, comment in cases: + # for i in range(n): + # Item.objects.create(text='itemy {}'.format(i), list=list_) + # response = self.client.get(f'/lists/{list_.id}/') + # self.assertIn(comment, response.content.decode()) + + def test_comment_only_for_no_todo(self): list_ = List.objects.create() - for n, comment in cases: - for i in range(n): - Item.objects.create(text='itemy {}'.format(i), list=list_) - response = self.client.get(f'/lists/{list_.id}/') - self.assertIn(comment, response.content.decode()) + response = self.client.get(f'/lists/{list_.id}/') + self.assertEqual(Item.objects.count(), 0) + self.assertIn('yey, waktunya berlibur', response.content.decode()) + + def test_comment_only_for_todo_morethan_5(self): + list_ = List.objects.create() + for i in range(6): + Item.objects.create(text='itemey {}'.format(i), list=list_) + response = self.client.get(f'/lists/{list_.id}/') + self.assertIn('OH TIDAKKK', response.content.decode()) + + def test_comment_only_for_todo_lessthan_5(self): + list_ = List.objects.create() + for i in range(2): + Item.objects.create(text='itemey {}'.format(i), list=list_) + response = self.client.get(f'/lists/{list_.id}/') + self.assertIn('sibuk tapi santai', response.content.decode()) def test_home_page_contains_name(self): request = HttpRequest() diff --git a/lists/views.py b/lists/views.py index d4c61b1..b9131e1 100644 --- a/lists/views.py +++ b/lists/views.py @@ -10,7 +10,15 @@ def home_page(request, error=''): def view_list(request, list_id, error=''): list_ = List.objects.get(id=list_id) items = Item.objects.filter(list=list_) - return render(request, 'list.html', {'list': list_,'items': items, 'error': error}) + if len(items) >= 5: + comment = "OH TIDAKKK" + elif len(items) >= 1: + comment = "sibuk tapi santai" + else: + comment = "yey, waktunya berlibur" + + return render(request, 'list.html', {'list': list_, 'items': items, 'comment': comment, 'error': error}) + def new_list(request): if (len(request.POST['item_text']) == 0): -- GitLab From b0ad450e2b6dce0d8315a4caeda6a78e4b2bba2e Mon Sep 17 00:00:00 2001 From: Aviliani Pramestya Date: Thu, 7 Nov 2019 20:28:23 +0700 Subject: [PATCH 7/7] Update README.md --- README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 942139a..e94df8e 100644 --- a/README.md +++ b/README.md @@ -70,4 +70,60 @@ Selanjutnya `green` berarti developer membuat production code yang akan membuat Sedangkan `refactor` berarti developer menambahkan atau memodifikasi production code yang sudah dibuat sebelumnya agar code tersebut lebih optimal serta dapat meningkatkan readability dan maintanability. Pada refactor ini biasanya developer akan membersihkan code smells yang ada pada production code, seperti code yang duplicate, method yang terlalu panjang, dan code smells lainnya. Refactor seharusnya tidak mengubah implementasi dari production code yang telah dibuat, namun hanya mengubah bagaimana implementasi tersebut dijalankan dengan lebih rapi. -Test Organizations yang saya lakukan pada exercise 5 ini memberikan kejelasan tentang test mana yang bertanggung jawab pada suatu aktivitas. Test yang dibuat akan menjadi lebih mudah dibaca karena adanya pemisahan pada setiap test yang melakukan aktivitas berbeda. \ No newline at end of file +Test Organizations yang saya lakukan pada exercise 5 ini memberikan kejelasan tentang test mana yang bertanggung jawab pada suatu aktivitas. Test yang dibuat akan menjadi lebih mudah dibaca karena adanya pemisahan pada setiap test yang melakukan aktivitas berbeda. + + +## Exercise 6 + +Pada awalnya fungsi untuk menampilkan comment yang ada pada exercise sebelumnya saya taruh pada html. Kali ini saya memindahkannya pada views seperti berikut: +``` +def view_list(request, list_id, error=''): + list_ = List.objects.get(id=list_id) + items = Item.objects.filter(list=list_) + if len(items) >= 5: + comment = "OH TIDAKKK" + elif len(items) >= 1: + comment = "sibuk tapi santai" + else: + comment = "yey, waktunya berlibur" + + return render(request, 'list.html', {'list': list_, 'items': items, 'comment': comment, 'error': error}) +``` + +Selanjutnya berdasarkan code di atas, saya membuat 2 buah mutant dengan menggunakan Relational Operator Replacement (ROR). Pada mutant pertama saya mengubah code ``if len(items) >= 5`` menjadi ``if len(items) < 5``. Sedangkan pada mutant kedua saya mengubah code ``elif len(items) >= 1`` menjadi ``elif len(items) == 1``. + +Test case baru yang saya buat untuk meng-kill kedua mutant di atas adalah sebagai berikut: +``` + def test_comment_only_for_no_todo(self): + list_ = List.objects.create() + response = self.client.get(f'/lists/{list_.id}/') + self.assertEqual(Item.objects.count(), 0) + self.assertIn('yey, waktunya berlibur', response.content.decode()) + + def test_comment_only_for_todo_morethan_5(self): + list_ = List.objects.create() + for i in range(6): + Item.objects.create(text='itemey {}'.format(i), list=list_) + response = self.client.get(f'/lists/{list_.id}/') + self.assertIn('OH TIDAKKK', response.content.decode()) + + def test_comment_only_for_todo_lessthan_5(self): + list_ = List.objects.create() + for i in range(2): + Item.objects.create(text='itemey {}'.format(i), list=list_) + response = self.client.get(f'/lists/{list_.id}/') + self.assertIn('sibuk tapi santai', response.content.decode()) +``` + +### Django Mutpy + +Selanjutnya saya melakukan mutation testing dengan menggunakan django-mutpy. Dengan command ``python manage.py muttest lists --modules lists.views lists.models`` didapatkan hasil sebagai berikut: +``` +[0.08386 s] killed by test_root_url_resolves_to_home_page_view (lists.tests.test_views.HomePageTest) +[*] Mutation score [7.21336 s]: 100.0% + - all: 41 + - killed: 41 (100.0%) + - survived: 0 (0.0%) + - incompetent: 0 (0.0%) + - timeout: 0 (0.0%) +``` \ No newline at end of file -- GitLab