Source code for webdriver_test_tools.project.test_factory

"""Functions for generating test cases"""

import unittest

from webdriver_test_tools.project import test_loader
from webdriver_test_tools.testcase import *


[docs]def generate_browser_test_suite(test_case_list, browser_test_classes=None, test_class_map=None, skip_class_map=None, config_module=None, browserstack=False, headless=False): """Generates test cases for multiple browsers and returns a TestSuite with all of the new tests :param test_case_list: A list of :class:`WebDriverTestCase <webdriver_test_tools.testcase.webdriver.WebDriverTestCase>` subclasses to generate a test suite for :param browser_test_classes: (Optional) If specified, only generate tests using the browser classes in this list. If not specified, tests will be generated for each available browser test case class. :param test_class_map: (Optional) Dictionary mapping test case names to a list of test functions. If the list is empty, all test functions will be loaded :param skip_class_map: (Optional) Dictionary mapping test case names to a list of test functions. If the list is empty, entire class will be skipped :param config_module: (Optional) The module object for ``<test_project>.config`` :param browserstack: (Default = False) If True, configure generated test cases to run on BrowserStack instead of locally. Need to provide ``config_module`` with appropriately configured :class:`BrowserStackConfig <webdriver_test_tools.config.browser.BrowserStackConfig>` class if set to True :param headless: (Default = False) If True, configure driver to run tests in a headless browser. Tests will only be generated for drivers that support running headless browsers :return: ``unittest.TestSuite`` object with generated tests for each browser """ # if headless, only use compatible browsers in browser_test_classes if headless: if browser_test_classes is None: browser_test_classes = [ browser_test_class for browser_test_class in Browsers.HEADLESS_COMPATIBLE if browser_test_class in config_module.BrowserConfig.get_browser_classes() ] else: browser_test_classes = [ browser_test_class for browser_test_class in browser_test_classes if browser_test_class in Browsers.HEADLESS_COMPATIBLE ] browser_tests = [] # Generate test classes for each test case in the list for test_case in test_case_list: generated_tests = generate_browser_test_cases(test_case, browser_test_classes, config_module, browserstack, headless) test_methods = _get_test_methods(test_case.__name__, test_class_map) skip_methods = _get_test_methods(test_case.__name__, skip_class_map) loaded_tests = test_loader.load_browser_tests( test_case, generated_tests, test_methods, skip_methods ) browser_tests.extend(loaded_tests) return unittest.TestSuite(browser_tests)
def _get_test_methods(test_case_name, test_class_map): """Takes ``test_class_map`` or ``skip_class_map`` and returns the list of methods for the test case or ``None`` if no methods were specified for it :param test_case_name: Name of the test case to check :param test_class_map: Dictionary mapping test names to a list of methods :return: List of methods or ``None`` if not specified for this test case """ if test_class_map is None or test_case_name not in test_class_map: return None return test_class_map[test_case_name]
[docs]def generate_browser_test_cases(base_class, browser_test_classes=None, config_module=None, browserstack=False, headless=False): """Generate test cases for each browser from a :class:`WebDriverTestCase <webdriver_test_tools.testcase.webdriver.WebDriverTestCase>` subclass :param base_class: The :class:`WebDriverTestCase <webdriver_test_tools.testcase.webdriver.WebDriverTestCase>` subclass to generate test classes for :param browser_test_classes: (Optional) If specified, only generate tests using the browser classes specified in this list. If not specified, tests will be generated for each available browser test case class :param config_module: (Optional) The module object for ``<test_project>.config`` :param browserstack: (Default = False) If True, configure generated test cases to run on BrowserStack instead of locally. Need to provide ``config_module`` with appropriately configured :class:`BrowserStackConfig <webdriver_test_tools.config.browser.BrowserStackConfig>` class if set to True :param headless: (Default = False) If True, configure driver to run tests in a headless browser :return: List of generated test case classes for each browser """ # generate class only for browser_test_class if specified browser_classes = config_module.BrowserConfig.get_browser_classes() if browser_test_classes is None else browser_test_classes # If this test is for non-mobile only, don't generate tests for subclasses of WebDriverMobileTestCase if base_class.SKIP_MOBILE: browser_classes = [ browser_class for browser_class in browser_classes if not issubclass(browser_class, WebDriverMobileTestCase) ] # If this test is a subclass of WebDriverMobileTestCase, then only generate tests for subclasses of WebDriverMobileTestCase elif issubclass(base_class, WebDriverMobileTestCase): browser_classes = [ browser_class for browser_class in browser_classes if issubclass(browser_class, WebDriverMobileTestCase) ] # iterate through a list of browser classes and generate test cases # skip browser classes if listed in base_class.SKIP_BROWSERS browser_test_cases = [ generate_browser_test_case(base_class, browser_class, config_module, browserstack, headless) for browser_class in browser_classes if browser_class.SHORT_NAME not in base_class.SKIP_BROWSERS ] return browser_test_cases
[docs]def generate_browser_test_case(base_class, browser_test_class, config_module=None, browserstack=False, headless=False): """Generates a browser-specific test case class from a generic :class:`WebDriverTestCase <webdriver_test_tools.testcase.webdriver.WebDriverTestCase>` :param base_class: :class:`WebDriverTestCase <webdriver_test_tools.testcase.webdriver.WebDriverTestCase>` containing test functions :param browser_test_class: The driver-specific implementation of :class:`WebDriverTestCase <webdriver_test_tools.testcase.webdriver.WebDriverTestCase>` to generate a test for :param config_module: (Optional) The module object for ``<test_project>.config`` :param browserstack: (Default = False) If True, configure generated test cases to run on BrowserStack instead of locally. Need to provide ``config_module`` with appropriately configured :class:`BrowserStackConfig <webdriver_test_tools.config.browser.BrowserStackConfig>` class if set to True :param headless: (Default = False) If True, configure driver to run tests in a headless browser :return: Test case class with tests from ``base_class`` and driver configurations from ``browser_test_class``. If ``browserstack`` is set to True, returned class will have appropriate attributes configured for BrowserStack execution. If ``headless`` is set to True, returned class will have appropriate attributes configured for headless browser execution. """ # Get base class attributes base_class_name = base_class.__name__ base_class_doc = base_class_name if base_class.__doc__ is None else base_class.__doc__ base_class_module = base_class.__module__ # Append the driver name portion of <Driver>TestCase to the class name browser_class_suffix = browser_test_class.__name__.replace('TestCase', '') new_class_name = base_class_name + browser_class_suffix # Use modified docstring and original module name from base class new_class_dict = { '__doc__': '({}) '.format(browser_test_class.DRIVER_NAME) + base_class_doc, '__module__': base_class_module, } # Use project's WebDriverConfig class if it exists if 'WebDriverConfig' in dir(config_module): new_class_dict['WebDriverConfig'] = config_module.WebDriverConfig new_class = type(new_class_name, (base_class, browser_test_class), new_class_dict) # Enable BrowserStack execution if browserstack: new_class = enable_browserstack(new_class, config_module) # Enable headless browsers if headless: new_class = enable_headless(new_class) return new_class
[docs]def enable_browserstack(browser_test_case, config_module): """Enable BrowserStack test execution for a class :param browser_test_case: Browser test case class to configure for BrowserStack usage :param config_module: The module object for ``<test_project>.config`` :return: browser_test_case class with :attr:`ENABLE_BS <webdriver_test_tools.testcase.webdriver.WebDriverTestCase.ENABLE_BS>` and :attr:`COMMAND_EXECUTOR <webdriver_test_tools.testcase.webdriver.WebDriverTestCase.COMMAND_EXECUTOR>` attributes configured appropriately """ # Raise exception if somehow this method was called but BrowserStack is not configured/enabled if 'BrowserStackConfig' not in dir(config_module) or not config_module.BrowserStackConfig.ENABLE: raise Exception('BrowserStack is not enabled or BrowserStackConfig class could not be found.') bs_config = config_module.BrowserStackConfig browser_test_case.ENABLE_BS = True browser_test_case.COMMAND_EXECUTOR = bs_config.get_command_executor() bs_config.add_browserstack_capabilities(browser_test_case.CAPABILITIES) return browser_test_case
[docs]def enable_headless(browser_test_case): """Enable headless browser test execution for a class :param browser_test_case: Browser test case class to configure for BrowserStack usage :return: ``browser_test_case`` class with :attr:`ENABLE_HEADLESS <webdriver_test_tools.testcase.webdriver.WebDriverTestCase.ENABLE_HEADLESS>` attribute configured """ browser_test_case.ENABLE_HEADLESS = True return browser_test_case