From 92d554aab3ff63cc84ca34a4aaf8040f7fefc7c9 Mon Sep 17 00:00:00 2001 From: har0ke Date: Wed, 21 Aug 2019 01:01:53 +0200 Subject: [PATCH] Getting tests to work with TravisCI and Coveralls --- .travis.yml | 35 +++++++++++++++++++++++++++ README.md | 6 ++++- devel-requirements.txt | 2 ++ tallybill/settings.py | 3 +++ tests/test_first.py | 55 +++++++++++++++++++++++++----------------- 5 files changed, 78 insertions(+), 23 deletions(-) create mode 100644 .travis.yml create mode 100644 devel-requirements.txt diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c6b16f9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,35 @@ +language: python +python: + - "3.6" + +env: + global: + - MOZ_HEADLESS=1 + +addons: + firefox: latest-nightly + chrome: stable + + +before_install: + - wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/2.40/chromedriver_linux64.zip + - mkdir $HOME/chromedriver && unzip /tmp/chromedriver.zip -d $HOME/chromedriver + - export PATH=$HOME/chromedriver:$PATH + - wget -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-linux64.tar.gz + - mkdir $HOME/geckodriver && tar xvf /tmp/geckodriver.tar.gz -C $HOME/geckodriver + - export PATH=$HOME/geckodriver:$PATH + - firefox --version + - geckodriver --version + + +install: + - pip install -r requirements.txt + - pip install -r devel-requirements.txt + +script: + - coverage3 run --omit="./main/migrations/*" --include="./main/*","./tallybill/*" ./manage.py test + + +after_success: + - pip install coveralls + - coveralls \ No newline at end of file diff --git a/README.md b/README.md index 3ca0b58..bda477d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +[![Build Status](https://travis-ci.com/har0ke/tallybill.svg?branch=master)](https://travis-ci.com/har0ke/tallybill) +[![Coverage Status](https://coveralls.io/repos/github/har0ke/tallybill/badge.svg?branch=master)](https://coveralls.io/github/har0ke/tallybill?branch=master) + + # Tallybill An django based tally of shared resource for your community: @@ -10,7 +14,7 @@ An django based tally of shared resource for your community: Create a new python3 environment and install all dependencies: -`pip install -r requirements.txt`t +`pip install -r requirements.txt` ## Run Development Server To run the development sever run: diff --git a/devel-requirements.txt b/devel-requirements.txt new file mode 100644 index 0000000..6767491 --- /dev/null +++ b/devel-requirements.txt @@ -0,0 +1,2 @@ +coverage==4.5.1 +selenium==3.141.0 diff --git a/tallybill/settings.py b/tallybill/settings.py index d6bf7e3..311b32b 100644 --- a/tallybill/settings.py +++ b/tallybill/settings.py @@ -86,6 +86,9 @@ DATABASES = { 'timeout': 20, # in seconds # see also # https://docs.python.org/3.7/library/sqlite3.html#sqlite3.connect + }, + 'TEST': { + 'NAME': 'testdb.sqlite3', } } } diff --git a/tests/test_first.py b/tests/test_first.py index 0a21e62..21d8644 100644 --- a/tests/test_first.py +++ b/tests/test_first.py @@ -1,22 +1,22 @@ import datetime -import inspect from time import sleep from urllib import parse from django.contrib.auth.models import User from django.contrib.staticfiles.testing import StaticLiveServerTestCase -from django.core.servers.basehttp import WSGIServer -from django.test.testcases import LiveServerThread, QuietWSGIRequestHandler -from selenium.webdriver.chrome.webdriver import WebDriver -from selenium.webdriver.common.by import By +from selenium import webdriver from selenium.webdriver.common.keys import Keys -from selenium.webdriver.support import expected_conditions -from selenium.webdriver.support.wait import WebDriverWait from main.billing import BillingPeriod, RecalculateThread from main.models import Product, ProductType, IncomingInvoice, Order, Consumption, Inventory, ProductInventory, \ OutgoingInvoice, OutgoingInvoiceProductUserPosition, OutgoingInvoiceProductPosition, UserExtension +HEADLESS = True + +FIREFOX = "firefox" +CHROME = "chrome" +driver = FIREFOX + class TestCaseData1(object): @@ -71,12 +71,6 @@ class TestCaseData1(object): invoice.inventory.save() -class LiveServerSingleThread(LiveServerThread): - """Runs a single threaded server rather than multi threaded. Reverts https://github.com/django/django/pull/7832""" - - def _create_server(self): - return WSGIServer((self.host, self.port), QuietWSGIRequestHandler, allow_reuse_address=False) - def replace_input_value(web_element, value): web_element.send_keys(Keys.CONTROL + "a") web_element.send_keys(value) @@ -84,12 +78,24 @@ def replace_input_value(web_element, value): class CoverageTest(StaticLiveServerTestCase): - # server_thread_class = LiveServerSingleThread - @classmethod def setUpClass(cls): super().setUpClass() - cls.selenium = WebDriver() + + if driver == CHROME: + options = webdriver.ChromeOptions() + if HEADLESS: + options.add_argument("--headless") + options.add_argument("--disable-gpu") + cls.selenium = webdriver.Chrome(chrome_options=options) + elif driver == FIREFOX: + options = webdriver.FirefoxOptions() + profile = webdriver.FirefoxProfile() + if HEADLESS: + options.add_argument('-headless') + profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "text/csv") + cls.selenium = webdriver.Firefox(firefox_options=options, firefox_profile=profile) + cls.selenium.implicitly_wait(2) @classmethod @@ -98,8 +104,6 @@ class CoverageTest(StaticLiveServerTestCase): super().tearDownClass() def setUp(self): - self.recalculate_thread = RecalculateThread() - self.recalculate_thread.start() self.scenario_data = TestCaseData1() @@ -109,10 +113,14 @@ class CoverageTest(StaticLiveServerTestCase): password_input = self.selenium.find_element_by_name("password") password_input.send_keys('1234') self.selenium.find_element_by_xpath('//input[@value="Log in"]').click() + self.wait_for_page() self.assertEqual(parse.urlparse(self.selenium.current_url).path, "/") + self.recalculate_thread = RecalculateThread() + self.recalculate_thread.start() + def tearDown(self): self.recalculate_thread.running = False self.recalculate_thread.join() @@ -244,7 +252,6 @@ class CoverageTest(StaticLiveServerTestCase): self.selenium.find_element_by_xpath("//input[@name='each_cents/%d']" % order_id).send_keys(Keys.DELETE) self.selenium.find_element_by_xpath('//button[text()="Save"]').send_keys(Keys.NULL) - #sleep() self.selenium.find_element_by_xpath('//button[text()="Save"]').click() self.wait_for_page() @@ -330,7 +337,7 @@ class CoverageTest(StaticLiveServerTestCase): self.selenium.find_element_by_xpath('//button[text()="Save"]').click() self.wait_for_page() - sleep(1) # time to recalculate + sleep(2) # time to recalculate self.selenium.get('%s%s' % (self.live_server_url, '/inventories/')) self.wait_for_page() @@ -339,8 +346,12 @@ class CoverageTest(StaticLiveServerTestCase): self.assertEqual(len(self.get_simple_list_text()), 2) self.selenium.find_elements_by_class_name("list-group-item")[0].click() - for csv_a in self.selenium.find_elements_by_xpath('//a[@target="_blank"]'): - self.selenium.get(csv_a.get_attribute("href")) + + csv_links = self.selenium.find_elements_by_xpath('//a[@target="_blank"]') + self.assertEqual(2, len(csv_links)) + for csv in csv_links: + csv.click() + self.selenium.find_element_by_xpath("//button[text()='Submit Changes']").click() self.selenium.find_element_by_xpath("//button[text()='Submit']").click() self.assertEqual(len(self.selenium.find_elements_by_xpath("//button[text()='Submit Changes']")), 0)