使用不同浏览器的参数化测试

Parametrize tests using different browsers

我正在尝试使用 python 3:

通过 py.testwebdriver 实现测试参数化
import pytest
from selenium import webdriver
from urllib.parse import urljoin


BASE_URL = 'http://ya.ru'


class WebDriverWrapper(type):

    def __init__(self, base_url, *args, **kwargs):
        self._base_url = base_url
        super().__init__(*args, **kwargs)

    def get(self, url):
        url = urljoin(self._base_url, url)
        return super().get(url)


@pytest.yield_fixture(scope='session', params=['PhantomJS', 'Firefox'])
def driver(request, base_url=BASE_URL):

    _driver = None           

    if request.param == 'PhantomJS':
        class Driver(webdriver.PhantomJS):
            __metaclass__ = WebDriverWrapper
        _driver = Driver(base_url)

    elif request.param == 'Firefox':
        class Driver(webdriver.Firefox):
            __metaclass__ = WebDriverWrapper
        _driver = Driver(base_url)

    _driver.get('/')

    yield _driver
    _driver.quit()

所以.. 我有 WebDriverWrapper 必须换行,例如 webdriver.Firefox,需要 base_url 才能在代码中不再重复它; 然后我有 driver 夹具 params;每个测试都必须通过相应的 param 例如浏览器; 我用 meta 类

实现了它

在 py.test 下的 运行 代码之后,我收到多个错误:

==================================== ERRORS ====================================
_______________ ERROR at setup of test_case[PhantomJS-hsup-hsup] _______________

request = <SubRequest 'driver' for <Function 'test_case[PhantomJS-hsup-hsup]'>>
base_url = 'http://ya.ru'

    @pytest.yield_fixture(scope='session', params=['PhantomJS', 'Firefox'])
    def driver(request, base_url=BASE_URL):

        _driver = None


        if request.param == 'PhantomJS':
            class Driver(webdriver.PhantomJS):
                __metaclass__ = WebDriverWrapper
>           _driver = Driver(base_url)

File "/mnt/common/Projects/python/autotest-snippets/page_object/fixtures.py", line 31

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
File "/usr/local/lib/python3.4/dist-packages/selenium/webdriver/phantomjs/webdriver.py", line 50
in __init__
    self.service.start()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <selenium.webdriver.phantomjs.service.Service object at 0x7fc7a2721b70>

    def start(self):
        """
            Starts PhantomJS with GhostDriver.

            :Exceptions:
             - WebDriverException : Raised either when it can't start the service
               or when it can't connect to the service
            """
        try:
            self.process = subprocess.Popen(self.service_args, stdin=subprocess.PIPE,
                                            close_fds=platform.system() != 'Windows',
                                            stdout=self._log, stderr=self._log)

        except Exception as e:
>           raise WebDriverException("Unable to start phantomjs with ghostdriver.", e)
E           selenium.common.exceptions.WebDriverException: Message: Unable to start phantomjs with ghostdriver.
E           Screenshot: available via screen

File "/usr/local/lib/python3.4/dist-packages/selenium/webdriver/phantomjs/service.py", line 75
WebDriverException
________________ ERROR at setup of test_case[Firefox-hsup-hsup] ________________

request = <SubRequest 'driver' for <Function 'test_case[Firefox-hsup-hsup]'>>
base_url = 'http://ya.ru'

    @pytest.yield_fixture(scope='session', params=['PhantomJS', 'Firefox'])
    def driver(request, base_url=BASE_URL):

        _driver = None


        if request.param == 'PhantomJS':
            class Driver(webdriver.PhantomJS):
                __metaclass__ = WebDriverWrapper
            _driver = Driver(base_url)
        elif request.param == 'Firefox':
            class Driver(webdriver.Firefox):
                __metaclass__ = WebDriverWrapper
>           _driver = Driver(base_url)

File "/mnt/common/Projects/python/autotest-snippets/page_object/fixtures.py", line 35

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <fixtures.driver.<locals>.Driver object at 0x7fc7a26c5278>
firefox_profile = 'http://ya.ru', firefox_binary = None, timeout = 30
capabilities = None, proxy = None

    def __init__(self, firefox_profile=None, firefox_binary=None, timeout=30,
                 capabilities=None, proxy=None):

        self.binary = firefox_binary
        self.profile = firefox_profile

        if self.profile is None:
            self.profile = FirefoxProfile()

        self.profile.native_events_enabled = (
>           self.NATIVE_EVENTS_ALLOWED and self.profile.native_events_enabled)
E       AttributeError: 'str' object has no attribute 'native_events_enabled'

File "/usr/local/lib/python3.4/dist-packages/selenium/webdriver/firefox/webdriver.py", line 46
AttributeError
=========================== 2 error in 0.13 seconds ============================

如何解决?

解决方法:

def Driver(klass, base_url):

    class WebDriverWrapper(klass):

        def __init__(self, base_url, *args, **kwargs):
            self._base_url = base_url
            super().__init__(*args, **kwargs)

        def get(self, url):
            url = urljoin(self._base_url, url)
            return super().get(url)

    return WebDriverWrapper(base_url) 

@pytest.yield_fixture(scope='session', params=[
    ('PhantomJS', webdriver.PhantomJS), 
    ('Firefox',   webdriver.Firefox)
])
def driver(request, base_url=BASE_URL):
    _driver = Driver(request.param[1], base_url)    
    _driver.get('/')
    yield _driver
    _driver.quit()