From 17a78714af4a80aea9b3b1697f3a351fedaa2f5f Mon Sep 17 00:00:00 2001 From: Izzatul Muttaqin Date: Mon, 23 Dec 2019 11:00:58 +0700 Subject: [PATCH 1/6] Buat git ci script untuk test --- .gitlab-ci.yml | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7c4d831..05832a0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ stages: - test - deploy - # - functional_test + - functional_test UnitTest: image: python:3.6 @@ -18,6 +18,24 @@ UnitTest: - coverage run manage.py test practice - coverage report -m +TestFunctional: + image: python:3.6 + stage: test_functional + before_script: + - 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 + - pip3 install -r requirements.txt + - apt-get update -qq && apt-get install -y -qq unzip + - apt-get install -y google-chrome-stable + - apt-get install -y xvfb + - wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.zip + - unzip chromedriver_linux64.zip + when: on_success + script: + - python3 manage.py makemigrations + - python3 manage.py migrate + - python3 manage.py test functional_test + Deployment: image: ruby:2.4 stage: deploy @@ -33,24 +51,4 @@ Deployment: name: production url: $HEROKU_APP_HOST only: - - master - -# FunctionalTest: -# image: python:3.6 -# stage: functional_test -# before_script: -# - 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 -# - pip3 install -r requirements.txt -# - pip3 install requests -# - pip3 install django-environ -# - apt-get update -qq && apt-get install -y -qq unzip -# - apt-get install -y google-chrome-stable -# - apt-get install -y xvfb -# - wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.zip -# - unzip chromedriver_linux64.zip -# when: on_success -# script: -# - python3 functional_tests.py -# only: -# - master + - master \ No newline at end of file -- GitLab From 2663692168a6f0a90b8caece5d64dd94b18cb63d Mon Sep 17 00:00:00 2001 From: Izzatul Muttaqin Date: Mon, 23 Dec 2019 11:05:08 +0700 Subject: [PATCH 2/6] Change tests --- .gitlab-ci.yml | 4 +- functional_test/tests.py | 109 +++++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 05832a0..660abe0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ stages: - test - - deploy - functional_test + - deploy UnitTest: image: python:3.6 @@ -20,7 +20,7 @@ UnitTest: TestFunctional: image: python:3.6 - stage: test_functional + stage: functional_test before_script: - 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 diff --git a/functional_test/tests.py b/functional_test/tests.py index 009e93a..0901d3a 100644 --- a/functional_test/tests.py +++ b/functional_test/tests.py @@ -1,70 +1,79 @@ +import sys +import time + +from django.contrib.staticfiles.testing import StaticLiveServerTestCase from selenium import webdriver from selenium.common.exceptions import WebDriverException -from selenium.webdriver.common.keys import Keys -from selenium.webdriver.common.by import By -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions from selenium.webdriver.chrome.options import Options -from django.test import LiveServerTestCase -import time -import unittest -import environ -MAX_WAIT = 5 +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 NewVisitorTest(LiveServerTestCase): + @classmethod + def setUpClass(cls): + for arg in sys.argv: + if 'liveserver' in arg: + cls.server_url = 'http://' + arg.split('=')[1] + return + super().setUpClass() + cls.server_url = cls.live_server_url def setUp(self): - self.browser = webdriver.Chrome() + chrome_options = Options() + chrome_options.add_argument('--dns-prefetch-disable') + chrome_options.add_argument('--no-sandbox') + chrome_options.add_argument('--headless') + chrome_options.add_argument('disable-gpu') + try: + self.browser = webdriver.Chrome('./chromedriver.exe', chrome_options=chrome_options) + except: + self.browser = webdriver.Chrome('./chromedriver', chrome_options=chrome_options) def tearDown(self): self.browser.quit() - def check_for_row(self, row_text): + def check_for_row_in_list_table(self, row_text): 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]) - def test_can_start_a_list_and_retrieve_it_later(self): - self.browser.get(self.live_server_url) + def get_item_input_box(self): + return self.browser.find_element_by_id('id_new_item') - self.assertIn('To-Do', self.browser.title) - header_text = self.browser.find_element_by_tag_name('h1').text - self.assertIn('To-Do', header_text) - - introduction = self.browser.find_element_by_id("intro") - self.assertIn('Izzatul', introduction.text) - - comment = self.browser.find_element_by_id('comment') - self.assertEqual(comment.text, 'yey, waktunya libur') - - inputbox = self.browser.find_element_by_id('id_new_item') - self.assertEqual( - inputbox.get_attribute('placeholder'), - 'Enter a to-do item' - ) - - inputbox.send_keys('Buy peacock feathers') - - inputbox.send_keys(Keys.ENTER) - WebDriverWait(self.browser, 10).until( - expected_conditions.text_to_be_present_in_element( - (By.ID, 'id_list_table'), 'Buy peacock feathers')) - self.check_for_row('1: Buy peacock feathers') - - inputbox = self.browser.find_element_by_id('id_new_item') - inputbox.send_keys('Use peacock feathers to make a fly') - inputbox.send_keys(Keys.ENTER) + @wait + def wait_for(self, fn): + return fn() + @wait + def wait_for_row_in_list_table(self, row_text): table = self.browser.find_element_by_id('id_list_table') rows = table.find_elements_by_tag_name('tr') - self.check_for_row('1: Buy peacock feathers') - WebDriverWait(self.browser, 10).until( - expected_conditions.text_to_be_present_in_element( - (By.ID, 'id_list_table'), 'Use peacock feathers to make a fly')) - self.check_for_row('2: Use peacock feathers to make a fly') - - # self.fail('Finish the test!') + self.assertIn(row_text, [row.text for row in rows]) -if __name__ == '__main__': - unittest.main(warnings='ignore') + @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) \ No newline at end of file -- GitLab From 3bd87c68bb750010e78a2061e6ba272df8cd623c Mon Sep 17 00:00:00 2001 From: Izzatul Muttaqin Date: Mon, 23 Dec 2019 11:07:04 +0700 Subject: [PATCH 3/6] Buat git ci script untuk test --- .gitlab-ci.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 660abe0..4792bfb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,20 +3,19 @@ stages: - functional_test - deploy -UnitTest: +Test: image: python:3.6 stage: test before_script: + - pip3 install --upgrade pip - pip3 install -r requirements.txt - - pip3 install requests - - pip3 install django-environ + script: - python3 manage.py makemigrations - python3 manage.py migrate - - python3 manage.py runserver 8000 & - when: on_success - script: - - coverage run manage.py test practice - - coverage report -m + - python3 manage.py test excercise1 + tags: + - test + TestFunctional: image: python:3.6 -- GitLab From 0eb0b6f99fa334a16afbf75b483cbf938928e0b8 Mon Sep 17 00:00:00 2001 From: Izzatul Muttaqin Date: Mon, 23 Dec 2019 11:14:49 +0700 Subject: [PATCH 4/6] Ubah ci dan memperbaik functional_test untuk tugas lama --- .gitlab-ci.yml | 2 +- functional_test/test_list.py | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 functional_test/test_list.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4792bfb..429e75c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,7 +12,7 @@ Test: script: - python3 manage.py makemigrations - python3 manage.py migrate - - python3 manage.py test excercise1 + - python3 manage.py test practice tags: - test diff --git a/functional_test/test_list.py b/functional_test/test_list.py new file mode 100644 index 0000000..e027cda --- /dev/null +++ b/functional_test/test_list.py @@ -0,0 +1,26 @@ +from selenium.webdriver.common.keys import Keys + +from .tests import FunctionalTest + +class ItemValidationTest(FunctionalTest): + + def test_item_validation(self): + self.browser.get(self.live_server_url) + self.get_item_input_box().send_keys(Keys.ENTER) + + self.wait_for(lambda: self.browser.find_elements_by_css_selector( + '#id_text:invalid' + )) + + self.get_item_input_box().send_keys('Buy milk') + self.wait_for(lambda: self.browser.find_elements_by_css_selector( + '#id_text:valid' + )) + + self.get_item_input_box().send_keys(Keys.ENTER) + self.wait_for_row_in_list_table('2: Buy milk') + + self.get_item_input_box().send_keys('Buy cheese') + self.get_item_input_box().send_keys(Keys.ENTER) + + self.wait_for_row_in_list_table('3: Buy cheese') \ No newline at end of file -- GitLab From 174ed3992c0b1e0d69c69c5f57855433a8ce5b4e Mon Sep 17 00:00:00 2001 From: Izzatul Muttaqin Date: Mon, 23 Dec 2019 11:46:11 +0700 Subject: [PATCH 5/6] Ubah setting --- testproject/settings.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testproject/settings.py b/testproject/settings.py index 41a8ddb..44d9a92 100644 --- a/testproject/settings.py +++ b/testproject/settings.py @@ -11,10 +11,11 @@ https://docs.djangoproject.com/en/2.2/ref/settings/ """ import os - +import socket +import dj_database_url # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - +PRODUCTION = os.environ.get('DATABASE_URL') != None # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ -- GitLab From e03f9511f25128f05830fe4399998a2da792155b Mon Sep 17 00:00:00 2001 From: Izzatul Muttaqin Date: Mon, 23 Dec 2019 12:38:48 +0700 Subject: [PATCH 6/6] Revamp --- .gitlab-ci.yml | 4 ++-- {practice => lists}/__init__.py | 0 {practice => lists}/admin.py | 0 lists/apps.py | 5 +++++ {practice => lists}/helper.py | 0 {practice => lists}/models.py | 2 +- {practice => lists}/templates/homepage/home.html | 0 {practice => lists}/tests.py | 0 {practice => lists}/urls.py | 0 {practice => lists}/views.py | 0 practice/apps.py | 5 ----- testproject/settings.py | 2 +- testproject/urls.py | 4 ++-- 13 files changed, 11 insertions(+), 11 deletions(-) rename {practice => lists}/__init__.py (100%) rename {practice => lists}/admin.py (100%) create mode 100644 lists/apps.py rename {practice => lists}/helper.py (100%) rename {practice => lists}/models.py (58%) rename {practice => lists}/templates/homepage/home.html (100%) rename {practice => lists}/tests.py (100%) rename {practice => lists}/urls.py (100%) rename {practice => lists}/views.py (100%) delete mode 100644 practice/apps.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 429e75c..c470586 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,7 +3,7 @@ stages: - functional_test - deploy -Test: +UnitTest: image: python:3.6 stage: test before_script: @@ -12,7 +12,7 @@ Test: script: - python3 manage.py makemigrations - python3 manage.py migrate - - python3 manage.py test practice + - python3 manage.py test lists tags: - test diff --git a/practice/__init__.py b/lists/__init__.py similarity index 100% rename from practice/__init__.py rename to lists/__init__.py diff --git a/practice/admin.py b/lists/admin.py similarity index 100% rename from practice/admin.py rename to lists/admin.py diff --git a/lists/apps.py b/lists/apps.py new file mode 100644 index 0000000..efe43f0 --- /dev/null +++ b/lists/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ListsConfig(AppConfig): + name = 'lists' diff --git a/practice/helper.py b/lists/helper.py similarity index 100% rename from practice/helper.py rename to lists/helper.py diff --git a/practice/models.py b/lists/models.py similarity index 58% rename from practice/models.py rename to lists/models.py index 201edc2..7ba0fdd 100644 --- a/practice/models.py +++ b/lists/models.py @@ -1,4 +1,4 @@ from django.db import models class Item(models.Model): - text = models.TextField(default='') + text = models.TextField(default='') \ No newline at end of file diff --git a/practice/templates/homepage/home.html b/lists/templates/homepage/home.html similarity index 100% rename from practice/templates/homepage/home.html rename to lists/templates/homepage/home.html diff --git a/practice/tests.py b/lists/tests.py similarity index 100% rename from practice/tests.py rename to lists/tests.py diff --git a/practice/urls.py b/lists/urls.py similarity index 100% rename from practice/urls.py rename to lists/urls.py diff --git a/practice/views.py b/lists/views.py similarity index 100% rename from practice/views.py rename to lists/views.py diff --git a/practice/apps.py b/practice/apps.py deleted file mode 100644 index e84e85b..0000000 --- a/practice/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class PracticeConfig(AppConfig): - name = 'practice' diff --git a/testproject/settings.py b/testproject/settings.py index 44d9a92..5d73af6 100644 --- a/testproject/settings.py +++ b/testproject/settings.py @@ -38,7 +38,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'practice', + 'lists' ] MIDDLEWARE = [ diff --git a/testproject/urls.py b/testproject/urls.py index bf62cb5..8e8e212 100644 --- a/testproject/urls.py +++ b/testproject/urls.py @@ -17,9 +17,9 @@ from django.contrib import admin from django.urls import path from django.conf.urls import url, include -import practice.urls as practice +import lists.urls as lists urlpatterns = [ path('admin/', admin.site.urls), - url(r'^', include((practice, 'practice'), namespace='practice')), + url(r'^', include((lists, 'lists'), namespace='lists')), ] -- GitLab