From 52bc460dffa6497a2074178d74aafeeeae0be292 Mon Sep 17 00:00:00 2001 From: "George Gelashvili, Sarah McAlear and Tira Odhner" Date: Tue, 21 Feb 2017 11:25:36 -0500 Subject: [PATCH 1/2] Rename acceptance -> feature_tests and make tests less flaky by tearing down the database connection before running the test --- .../{acceptance => feature_tests}/__init__.py | 0 .../connect_to_server_feature_test.py | 22 +++--------------- .../template_selection_feature_test.py | 24 ++++---------------- web/pgadmin/utils/route.py | 2 +- web/regression/README | 6 ++--- .../tests => regression/feature_utils}/__init__.py | 0 .../{utils => feature_utils}/app_starter.py | 0 web/regression/feature_utils/base_feature_test.py | 26 ++++++++++++++++++++++ .../{utils => feature_utils}/pgadmin_page.py | 6 ++++- web/regression/test_utils.py | 5 +++++ web/regression/utils/__init__.py | 0 11 files changed, 47 insertions(+), 44 deletions(-) rename web/pgadmin/{acceptance => feature_tests}/__init__.py (100%) rename web/pgadmin/{acceptance/tests => feature_tests}/connect_to_server_feature_test.py (78%) rename web/pgadmin/{acceptance/tests => feature_tests}/template_selection_feature_test.py (74%) rename web/{pgadmin/acceptance/tests => regression/feature_utils}/__init__.py (100%) rename web/regression/{utils => feature_utils}/app_starter.py (100%) create mode 100644 web/regression/feature_utils/base_feature_test.py rename web/regression/{utils => feature_utils}/pgadmin_page.py (95%) delete mode 100644 web/regression/utils/__init__.py diff --git a/web/pgadmin/acceptance/__init__.py b/web/pgadmin/feature_tests/__init__.py similarity index 100% rename from web/pgadmin/acceptance/__init__.py rename to web/pgadmin/feature_tests/__init__.py diff --git a/web/pgadmin/acceptance/tests/connect_to_server_feature_test.py b/web/pgadmin/feature_tests/connect_to_server_feature_test.py similarity index 78% rename from web/pgadmin/acceptance/tests/connect_to_server_feature_test.py rename to web/pgadmin/feature_tests/connect_to_server_feature_test.py index c3bee4e6..2a7f638e 100644 --- a/web/pgadmin/acceptance/tests/connect_to_server_feature_test.py +++ b/web/pgadmin/feature_tests/connect_to_server_feature_test.py @@ -7,29 +7,20 @@ # ############################################################## -from selenium import webdriver from selenium.webdriver import ActionChains import config as app_config -from pgadmin.utils.route import BaseTestGenerator from regression import test_utils -from regression.utils.app_starter import AppStarter -from regression.utils.pgadmin_page import PgadminPage +from regression.feature_utils.base_feature_test import BaseFeatureTest -class ConnectsToServerFeatureTest(BaseTestGenerator): +class ConnectsToServerFeatureTest(BaseFeatureTest): """ Tests that a database connection can be created from the UI """ def setUp(self): - if app_config.SERVER_MODE: - self.skipTest("Currently, config is set to start pgadmin in server mode. " - "This test doesn't know username and password so doesn't work in server mode") - - driver = webdriver.Chrome() - self.app_starter = AppStarter(driver, app_config) - self.page = PgadminPage(driver, app_config) + super(ConnectsToServerFeatureTest, self).setUp() connection = test_utils.get_db_connection(self.server['db'], self.server['username'], @@ -40,9 +31,6 @@ class ConnectsToServerFeatureTest(BaseTestGenerator): test_utils.create_database(self.server, "acceptance_test_db") test_utils.create_table(self.server, "acceptance_test_db", "test_table") - self.app_starter.start_app() - self.page.wait_for_app() - def runTest(self): self.assertEqual(app_config.APP_NAME, self.page.driver.title) self.page.wait_for_spinner_to_disappear() @@ -61,10 +49,6 @@ class ConnectsToServerFeatureTest(BaseTestGenerator): self.server['port']) test_utils.drop_database(connection, "acceptance_test_db") - def failureException(self, *args, **kwargs): - self.page.driver.save_screenshot('/tmp/pgadmin_connect_to_server_test_failure.png') - return AssertionError(*args, **kwargs) - def _connects_to_server(self): self.page.find_by_xpath("//*[@class='aciTreeText' and .='Servers']").click() self.page.driver.find_element_by_link_text("Object").click() diff --git a/web/pgadmin/acceptance/tests/template_selection_feature_test.py b/web/pgadmin/feature_tests/template_selection_feature_test.py similarity index 74% rename from web/pgadmin/acceptance/tests/template_selection_feature_test.py rename to web/pgadmin/feature_tests/template_selection_feature_test.py index b7405d56..858950f4 100644 --- a/web/pgadmin/acceptance/tests/template_selection_feature_test.py +++ b/web/pgadmin/feature_tests/template_selection_feature_test.py @@ -1,22 +1,13 @@ from selenium import webdriver from selenium.webdriver import ActionChains -import config as app_config -from pgadmin.utils.route import BaseTestGenerator from regression import test_utils -from regression.utils.app_starter import AppStarter -from regression.utils.pgadmin_page import PgadminPage +from regression.feature_utils.base_feature_test import BaseFeatureTest -class TemplateSelectionFeatureTest(BaseTestGenerator): +class TemplateSelectionFeatureTest(BaseFeatureTest): def setUp(self): - if app_config.SERVER_MODE: - self.skipTest("Currently, config is set to start pgadmin in server mode. " - "This test doesn't know username and password so doesn't work in server mode") - - driver = webdriver.Chrome() - self.app_starter = AppStarter(driver, app_config) - self.page = PgadminPage(driver, app_config) + super(TemplateSelectionFeatureTest, self).setUp() connection = test_utils.get_db_connection(self.server['db'], self.server['username'], @@ -27,9 +18,6 @@ class TemplateSelectionFeatureTest(BaseTestGenerator): test_utils.create_database(self.server, "acceptance_test_db") - self.app_starter.start_app() - self.page.wait_for_app() - self.page.add_server(self.server) def runTest(self): @@ -71,8 +59,4 @@ $BODY$ self.server['db_password'], self.server['host'], self.server['port']) - test_utils.drop_database(connection, "acceptance_test_db") - - def failureException(self, *args, **kwargs): - self.page.driver.save_screenshot('/tmp/pgadmin_sql_template_selection_failure.png') - return AssertionError(*args, **kwargs) + test_utils.drop_database(connection, "acceptance_test_db") \ No newline at end of file diff --git a/web/pgadmin/utils/route.py b/web/pgadmin/utils/route.py index 996892a6..2dea25d9 100644 --- a/web/pgadmin/utils/route.py +++ b/web/pgadmin/utils/route.py @@ -48,7 +48,7 @@ class TestsGeneratorRegistry(ABCMeta): # Register this type of module, based on the module name # Avoid registering the BaseDriver itself - if name != 'BaseTestGenerator': + if name != 'BaseTestGenerator' and name != 'BaseFeatureTest': TestsGeneratorRegistry.registry[d['__module__']] = cls ABCMeta.__init__(cls, name, bases, d) diff --git a/web/regression/README b/web/regression/README index 7101eb75..d16111b6 100644 --- a/web/regression/README +++ b/web/regression/README @@ -103,7 +103,7 @@ Test Data Details Execution: ----------- -- For acceptance tests to run as part of the entire test suite, Chrome and chromedriver need to be installed: +- For feature tests to run as part of the entire test suite, Chrome and chromedriver need to be installed: get chromedriver from https://sites.google.com/a/chromium.org/chromedriver/downloads or a package manager and make sure it is on the PATH @@ -137,8 +137,8 @@ Execution: - Exclude a package and its subpackages when running tests: - Example: exclude acceptance tests but run all others: - run 'python runtests.py --exclude acceptance' + Example: exclude feature tests but run all others: + run 'python runtests.py --exclude feature_tests' Example: exclude multiple packages: run 'python runtests.py --exclude browser.server_groups.servers.databases,browser.server_groups.servers.tablespaces' diff --git a/web/pgadmin/acceptance/tests/__init__.py b/web/regression/feature_utils/__init__.py similarity index 100% rename from web/pgadmin/acceptance/tests/__init__.py rename to web/regression/feature_utils/__init__.py diff --git a/web/regression/utils/app_starter.py b/web/regression/feature_utils/app_starter.py similarity index 100% rename from web/regression/utils/app_starter.py rename to web/regression/feature_utils/app_starter.py diff --git a/web/regression/feature_utils/base_feature_test.py b/web/regression/feature_utils/base_feature_test.py new file mode 100644 index 00000000..62d3bb36 --- /dev/null +++ b/web/regression/feature_utils/base_feature_test.py @@ -0,0 +1,26 @@ +from selenium import webdriver + +import config as app_config +from pgadmin.utils.route import BaseTestGenerator +from regression.feature_utils.app_starter import AppStarter +from regression.feature_utils.pgadmin_page import PgadminPage + + +class BaseFeatureTest(BaseTestGenerator): + def setUp(self): + if app_config.SERVER_MODE: + self.skipTest("Currently, config is set to start pgadmin in server mode. " + "This test doesn't know username and password so doesn't work in server mode") + + driver = webdriver.Chrome() + self.app_starter = AppStarter(driver, app_config) + self.page = PgadminPage(driver, app_config) + self.app_starter.start_app() + self.page.wait_for_app() + + def failureException(self, *args, **kwargs): + self.page.driver.save_screenshot('/tmp/feature_test_failure.png') + return AssertionError(*args, **kwargs) + + def runTest(self): + pass \ No newline at end of file diff --git a/web/regression/utils/pgadmin_page.py b/web/regression/feature_utils/pgadmin_page.py similarity index 95% rename from web/regression/utils/pgadmin_page.py rename to web/regression/feature_utils/pgadmin_page.py index d6a5836c..8d2843f6 100644 --- a/web/regression/utils/pgadmin_page.py +++ b/web/regression/feature_utils/pgadmin_page.py @@ -1,4 +1,5 @@ import time + from selenium.common.exceptions import NoSuchElementException from selenium.webdriver import ActionChains from selenium.webdriver.common.keys import Keys @@ -65,6 +66,9 @@ class PgadminPage: "//pre[contains(@class,'CodeMirror-line')]/../../../*[contains(@class,'CodeMirror-code')]").click() ActionChains(self.driver).send_keys(field_content).perform() + def click_tab(self, tab_name): + self.find_by_xpath("//*[contains(@class,'wcPanelTab') and contains(.,'" + tab_name + "')]").click() + def wait_for_input_field_content(self, field_name, content): def input_field_has_content(): element = self.driver.find_element_by_xpath( @@ -117,4 +121,4 @@ class PgadminPage: time_waited += sleep_time time.sleep(sleep_time) - raise RuntimeError("timed out waiting for " + waiting_for_message) + raise AssertionError("timed out waiting for " + waiting_for_message) diff --git a/web/regression/test_utils.py b/web/regression/test_utils.py index b4445d7d..1c2d244d 100644 --- a/web/regression/test_utils.py +++ b/web/regression/test_utils.py @@ -157,6 +157,11 @@ def drop_database(connection, database_name): """This function used to drop the database""" if database_name not in ["postgres", "template1", "template0"]: pg_cursor = connection.cursor() + + pg_cursor.execute( + "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity " + "WHERE pg_stat_activity.datname ='%s' and pid <> pg_backend_pid();" % database_name + ) pg_cursor.execute("SELECT * FROM pg_database db WHERE" " db.datname='%s'" % database_name) if pg_cursor.fetchall(): diff --git a/web/regression/utils/__init__.py b/web/regression/utils/__init__.py deleted file mode 100644 index e69de29b..00000000 -- 2.11.0