Fakultas Ilmu Komputer UI

Commit c29cef25 authored by Syahrul Findi's avatar Syahrul Findi
Browse files

Latihan9

parent 17b400ab
...@@ -29,3 +29,7 @@ Ketika kita sudah mengetahui bagaimana implementasi dari teknologi yang kita pel ...@@ -29,3 +29,7 @@ Ketika kita sudah mengetahui bagaimana implementasi dari teknologi yang kita pel
Manual mocking adalah implementasi mock dengan cara membuat sendiri method mock dari sebuah method yang mengembalikan nilai yang kita inginkan. Sedangkan jika kita menggunakan mock library, mock method dari method yang kita inginkan akan dibuatkan oleh library tersebut, kita hanya tinggal mengatur behavior dari mock tersebut. Manual mocking adalah implementasi mock dengan cara membuat sendiri method mock dari sebuah method yang mengembalikan nilai yang kita inginkan. Sedangkan jika kita menggunakan mock library, mock method dari method yang kita inginkan akan dibuatkan oleh library tersebut, kita hanya tinggal mengatur behavior dari mock tersebut.
Mocking dilakukan pada sebuah method yang dipanggil saat sebuah method dijalankan pada sebuah test. Artinya dalam implementasi method tersebut, setiap pemanggilannya akan bergantung pada method yang dibuat mocknya. Sebuah class/method yang memiliki ketergantungan tinggi dengan class/method lainnya disebut tightly coupled. Misalnya pada source code, setiap pemanggilan method GET untuk url login akan memanggil method auth pada accounts.views. Oleh sebab itu dapat disimpulkan bahwa method login tightly coupled dengan method auth. Mocking dilakukan pada sebuah method yang dipanggil saat sebuah method dijalankan pada sebuah test. Artinya dalam implementasi method tersebut, setiap pemanggilannya akan bergantung pada method yang dibuat mocknya. Sebuah class/method yang memiliki ketergantungan tinggi dengan class/method lainnya disebut tightly coupled. Misalnya pada source code, setiap pemanggilan method GET untuk url login akan memanggil method auth pada accounts.views. Oleh sebab itu dapat disimpulkan bahwa method login tightly coupled dengan method auth.
## Latihan 9
Pada section 18, funstional test dilakukan dengan melalui proses login terlebih dahulu, sehingga akan memakan banyak waktu. Sedangkan pada section 20, functional test dilakukan dengan memanfaatkan session dari login sebelumnya, sehingga untuk melakukan setiap functional test tidak perlu melalui proses login lagi.
...@@ -49,7 +49,7 @@ class SendLoginEmailViewTest(TestCase): ...@@ -49,7 +49,7 @@ class SendLoginEmailViewTest(TestCase):
'email': 'edith@example.com' 'email': 'edith@example.com'
}) })
token = Token.objects.first() token = Token.objects.first()
expected_url = f'http://testserver/accounts/login?token={token.uid}' expected_url = 'http://testserver/accounts/login?token=%s' % token.uid
(subject, body, from_email, to_list), kwargs = mock_send_mail.call_args (subject, body, from_email, to_list), kwargs = mock_send_mail.call_args
self.assertIn(expected_url, body) self.assertIn(expected_url, body)
......
...@@ -5,6 +5,18 @@ import time ...@@ -5,6 +5,18 @@ import time
MAX_WAIT = 10 MAX_WAIT = 10
def wait(fn):
def modified_fn(*args, **kwargs):
start_time = time.time()
while True:
try:
return fn(*args, **kwargs)
except (AssertionError, WebDriverException) as e:
if time.time() - start_time > MAX_WAIT:
raise e
time.sleep(0.5)
return modified_fn
class FunctionalTest(StaticLiveServerTestCase): class FunctionalTest(StaticLiveServerTestCase):
def setUp(self): def setUp(self):
...@@ -13,25 +25,25 @@ class FunctionalTest(StaticLiveServerTestCase): ...@@ -13,25 +25,25 @@ class FunctionalTest(StaticLiveServerTestCase):
def tearDown(self): def tearDown(self):
self.browser.quit() self.browser.quit()
@wait
def wait_for_row_in_list_table(self, row_text): def wait_for_row_in_list_table(self, row_text):
start_time = time.time() table = self.browser.find_element_by_id('id_list_table')
while True: rows = table.find_elements_by_tag_name('tr')
try: self.assertIn(row_text, [row.text for row in rows])
table = self.browser.find_element_by_id('id_list_table')
rows = table.find_elements_by_tag_name('tr')
self.assertIn(row_text, [row.text for row in rows])
return
except (AssertionError, WebDriverException) as e:
if time.time() - start_time > MAX_WAIT:
raise e
time.sleep(0.5)
@wait
def wait_for(self, fn): def wait_for(self, fn):
start_time = time.time() return fn()
while True:
try: @wait
return fn() def wait_to_be_logged_in(self, email):
except (AssertionError, WebDriverException) as e: self.browser.find_element_by_link_text('Log out')
if time.time() - start_time > MAX_WAIT: navbar = self.browser.find_element_by_css_selector('.navbar')
raise e self.assertIn(email, navbar.text)
time.sleep(0.5)
@wait
def wait_to_be_logged_out(self, email):
self.browser.find_element_by_name('email')
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertNotIn(email, navbar.text)
...@@ -39,24 +39,10 @@ class LoginTest(FunctionalTest): ...@@ -39,24 +39,10 @@ class LoginTest(FunctionalTest):
self.browser.get(url) self.browser.get(url)
# she is logged in! # she is logged in!
self.wait_for( self.wait_to_be_logged_in(email=TEST_EMAIL)
lambda: self.browser.find_element_by_link_text('Log out')
)
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertIn(TEST_EMAIL, navbar.text)
self.wait_for(
lambda: self.browser.find_element_by_link_text('Log out')
)
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertIn(TEST_EMAIL, navbar.text)
# Now she logs out # Now she logs out
self.browser.find_element_by_link_text('Log out').click() self.browser.find_element_by_link_text('Log out').click()
# She is logged out # She is logged out
self.wait_for( self.wait_to_be_logged_out(email=TEST_EMAIL)
lambda: self.browser.find_element_by_name('email')
)
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertNotIn(TEST_EMAIL, navbar.text)
from django.conf import settings
from django.contrib.auth import BACKEND_SESSION_KEY, SESSION_KEY, get_user_model
from django.contrib.sessions.backends.db import SessionStore
from .base import FunctionalTest
User = get_user_model()
class MyListsTest(FunctionalTest):
def create_pre_authenticated_session(self, email):
user = User.objects.create(email=email)
session = SessionStore()
session[SESSION_KEY] = user.pk
session[BACKEND_SESSION_KEY] = settings.AUTHENTICATION_BACKENDS[0]
session.save()
## to set a cookie we need to first visit the domain.
## 404 pages load the quickest!
self.browser.get(self.live_server_url + "/404_no_such_url/")
self.browser.add_cookie(dict(
name=settings.SESSION_COOKIE_NAME,
value=session.session_key,
path='/',
))
def test_logged_in_users_lists_are_saved_as_my_lists(self):
email = 'edith@example.com'
self.browser.get(self.live_server_url)
self.wait_to_be_logged_out(email)
# Edith is a logged-in user
self.create_pre_authenticated_session(email)
self.browser.get(self.live_server_url)
self.wait_to_be_logged_in(email)
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment