Fakultas Ilmu Komputer UI

Commit fa59f1d4 authored by RANI LASMA ULI's avatar RANI LASMA ULI
Browse files

Merge branch 'testinggoat/ex9' into 'master'

Testinggoat/ex9

See merge request !11
parents 59021c39 76cd0619
Pipeline #26352 passed with stages
in 3 minutes and 26 seconds
......@@ -31,27 +31,18 @@ Deployment:
url: $HEROKU_APP_HOST
FunctionalTest:
image: python:3.7
stage: functionalTest
image: joyzoursky/python-chromedriver
stage: test
before_script:
- wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh
- export HEROKU_API_KEY=$HEROKU_APIKEY
- heroku pg:reset DATABASE --app $HEROKU_NAME --confirm $HEROKU_NAME || true
- heroku restart --app $HEROKU_NAME || true
- heroku run --app $HEROKU_NAME migrate || true
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
- echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list
- apt-get update -qq && apt-get install -y -qq unzip
- apt-get install -y google-chrome-stable
- apt-get install -y xvfb
- pip install -r requirements.txt
- python3 manage.py migrate
- python3 manage.py compilescss
- python3 manage.py collectstatic --no-input
- wget https://chromedriver.storage.googleapis.com/77.0.3865.40/chromedriver_linux64.zip
- unzip chromedriver_linux64.zip
- pip install -r requirements.txt
when: on_success
allow_failure: true
script:
- python3 manage.py test functional_tests
after_script:
- heroku pg:reset DATABASE --app $HEROKU_NAME --confirm $HEROKU_NAME || true
- heroku run --app $HEROKU_NAME migrate || true
......@@ -9,6 +9,7 @@
- [Why Need Test Organization](#why-need-test-organization)
- [Mutation Testing](#mutation-testing)
- [Mocking Manually vs Library](#mocking-manually-vs-library)
- [Ch 20 vs Ch 18](#test-fixture-and-decorator)
- [URL](#url)
- [Install Modules](#install-modules)
......@@ -309,4 +310,14 @@ Also, using library for mocking is pretty simple - in this case just using @patc
>
> Mocking with Library:
> 1. Readable code, no object creation in testing class
> 2. Fully-package! No need to write the construct the object (fake) to mock real object
> 2. Fully-package! No need to write the constructor of the object (fake) to mock real object
#### Test Fixture and Decorator
Perbedaan antara Ch 20 vs Ch 18:
- Pada chapter 20, saya menggunakan method `create-pre-authenticated` yang berfungsi untuk membuat session. Session adalah cara browser untuk mengenali request HTTP yang dimana memiliki sifat stateless.
- Adanya penambahan `@wait` yang bertingkah laku sebagai decorator. Kode pada file `base.py` memiliki sejumlah pemanggilan fungsi `self.wait_for...` dimana pada fungsi-fungsi tersebut menggunakan fungsi `wait_for`. Melihat hal ini, refactor dapat dilakukan dengan membuat 1 fungsi bernama `wait`. Khusus untuk latihan kali ini, fungsi `wait` dibuat agar dapat diakses sebagai decorator (menerima fungsi sebagai parameter).
> Mengapa kode pada ch 20 lebih baik dari kode ch 18?
- Refactor sebuag fungsi yang sering dipakai menjadi fungsi yang dapat diakses sebagai decorator membuat kode menjadi lebih readable dan ringkas.
- Penggunaan session pada authentication itu adalah sebuah keharusan untuk HTTP dengan sifatnya yang stateless. FungsionalTest kali ini menjadi lebih sesuai dengan rekayasa penggunaan browser. Di tambah lagi, dengan adanya session kita dapat melayani user secara spesifik dan data pribadi (yang tidak terlalu penting namun sangat memungkinkan untuk dipakai berkali-kali) dapat disimpan pada session.
\ No newline at end of file
......@@ -10,6 +10,21 @@ from unittest import skip
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):
def setUp(self):
self.BASE_URL = os.environ.get("HEROKU_HOST", self.live_server_url)
......@@ -36,6 +51,7 @@ class FunctionalTest(StaticLiveServerTestCase):
def tearDown(self):
self.browser.quit()
@wait
def wait_for_row_in_list_table(self, row_text):
start_time = time.time()
while True:
......@@ -49,6 +65,7 @@ class FunctionalTest(StaticLiveServerTestCase):
raise e
time.sleep(0.5)
@wait
def wait_for(self, fn):
start_time = time.time()
while True:
......@@ -57,4 +74,17 @@ class FunctionalTest(StaticLiveServerTestCase):
except (AssertionError, WebDriverException) as e:
if time.time() - start_time > MAX_WAIT:
raise e
time.sleep(0.5)
\ No newline at end of file
time.sleep(0.5)
@wait
def wait_to_be_logged_in(self, email):
self.browser.find_element_by_link_text('Log out')
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertIn(email, navbar.text)
@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)
......@@ -42,15 +42,10 @@ class LoginTest(FunctionalTest):
self.browser.get(url)
# she is logged in!
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)
self.wait_to_be_logged_in(email=TEST_EMAIL)
# Now she logs out
self.browser.find_element_by_link_text('Log out').click()
# She is logged out
self.wait_for(lambda: self.browser.find_element_by_name('email'))
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertNotIn(TEST_EMAIL, navbar.text)
self.wait_to_be_logged_out(email=TEST_EMAIL)
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.BASE_URL)
self.wait_to_be_logged_out(email)
# Edith is a logged-in user
self.create_pre_authenticated_session(email)
self.browser.get(self.BASE_URL)
self.wait_to_be_logged_in(email)
Markdown is supported
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