并行获取每个浏览器的硒驱动程序

时间:2018-07-14 01:43:30

标签: python selenium

我正在寻找一种在云测试提供商上并行运行多个浏览器功能的方法。测试是用python编写的。我想我已经走了很多路,但是我很难将每个浏览器的驱动程序安装到tearDown上。该项目将包含针对多个站点的测试,并针对多种平台,浏览器,浏览器版本和屏幕尺寸运行。现在,我有一个最可重复的步骤的概念将放置在项目的顶层,并且所有子目录(即单个站点)都将导入到全局模块中。现在,这只是多个浏览器的设置。这样,我可以将每个子目录保留为仅测试本身。这是我所拥有的精简示例。

项目结构看起来像

├── initializer.py
└── sites
    ├── site1
    │   ├── test1.py
    │   ├── test2.py
    │   ├── requirements.txt
    │   ├── setup.py
    │   └── test.py
    └── site2
        ├── test1.py
        ├── test2.py
        ├── requirements.txt
        ├── setup.py
        └── test.py

这将是设置所有内容并将其导入子目录/站点initializer.py

的最高级别。
#!/usr/bin/env python

import os
import unittest
from threading import Thread
from selenium import webdriver
from desired_capabilities import *

API_EMAIL = os.environ["CBT_EMAIL"]
API_AUTH = os.environ["CBT_AUTH"]

class Setup(unittest.TestCase):

    def __init__(self):
        self.browsers = []
        self.browsers_waiting = []
        self.threads = []

    def setUp(self):
        for platform in platforms:
            # win
            if platform == "Windows 10":
                for version in win_10_chrome_versions:
                    self.gen_browser("Chrome", version, platform)
                for version in win_10_ff_versions:
                    self.gen_browser("Firefox", version, platform)
                for version in win_10_ie_versions:
                    self.gen_browser("Internet Explorer", version, platform)
            # mac
            elif platform == "Mac OSX 10.12":
                for version in mac_10_12_chrome_versions:
                    self.gen_browser("Chrome", version, platform)
                for version in mac_10_12_ff_versions:
                    self.gen_browser("Firefox", version, platform)
                for version in mac_10_12_safari_versions:
                    self.gen_browser("Safari", version, platform)

        for i, browser in enumerate(browsers):
            thread = Thread(target=self.get_browser_and_wait, args=[browser])
            self.threads.append(thread)
            thread.start()

        for thread in self.threads:
            thread.join()

        print ("\n\tAll browsers are setup and ready\n")

        for i, browser in enumerate(browsers_waiting):
            self.tearDown(browser) # I know this doesn't work, it's the approach I would like. tearDown doesn't allow another argument

    def get_browser_driver(self, caps):
        return webdriver.Remote(
                desired_capabilities=caps,
                command_executor="http://%s:%s@hub.crossbrowsertesting.com:80/wd/hub" % (API_EMAIL, API_AUTH)
            )

    def gen_browser(self, browser, version, platform):
        for resolution in desktop_screen_resolution:
            caps = {}
            caps['platform'] = platform
            caps['browserName'] = browser
            caps['version'] = version
            caps['screenResolution'] = resolution
            caps['name'] = 'Login Form Example'
            caps['build'] = '1.0'
            caps['record_video'] = 'false'
            caps['record_network'] = 'false'

            print ("Browser %s %s is now set up for %s at %s\n" % (browser, version, platform, resolution))

            self.browsers.append(caps)

    def get_browser_and_wait(self, browser_data):
        print ("Starting %s %s for %s at %s\n" % (browser_data["browserName"], browser_data["version"], browser_data["platform"], browser_data["screenResolution"]))
        driver = self.get_browser_driver(browser_data)
        browsers_waiting.append({"data": browser_data, "driver": driver})
        print ("%s %s at %s for %s is ready\n" % (browser_data["browserName"], browser_data["version"], browser_data["screenResolution"], browser_data["platform"]))

        while len(self.browsers_waiting) < len(self.browsers):
            print ("Working on %s for %s.... please wait" % (browser_data["browserName"], browser_data["platform"]))
            time.sleep(10)

    def tearDown(self):
        # This is where I'm stumpped
        # looping through the browsers_waiting doesnt work either
        if (self.driver != None):
            self.driver.close()
            self.driver.quit()

然后这是一个myproject/sites/sitename/test.py,它基本上是将调用所有测试的主要入口点脚本

#!/usr/bin/env python

from unittest import TestSuite, TextTestRunner, TestLoader
from example import exampleTest

def suite():
    loader = TestLoader()
    suite = TestSuite()
    suite.addTest(loader.loadTestsFromModule(exampleTest))
    return suite

if __name__ == '__main__':
    runner = TextTestRunner(verbosity=2)
    runner.run(suite())

这是我在{/ {1}}的child / site目录中进行的示例测试。

myproject/sites/sitename/example.py

我什至不确定这是否可行,或者我以这种方式进行设置的方法甚至是最好的方法。一旦所有的浏览器都设置好,和/或我无法访问每个浏览器的单个驱动程序,我将无法调用各个测试。将它们全部塞进浏览器数组后,self.driver不再可用。

仅供参考:{@ 3}}

来自CBT,

1 个答案:

答案 0 :(得分:0)

我不是线程专家,也不是python unittest模块专家,所以如果我的回答不能帮助您解决问题,则非常抱歉。

在您的example.py模块中,方法test_Header依赖于实例dict browsers_waiting实例,该实例在从初始化程序模块继承的类Setup中定义。当方法get_browser_and_wait被执行时,有问题的字典将填充键,值对。

因此,在这一点上,如果从未调用过get_browser_and_wait方法,那么您将遍历一个空字典

def test_Header(self):
    for i, browser in enumerate(Setup().browsers_waiting):
        # this does not work
        driver = browser["driver"]
        self.test_result = None

再说一次,我不知道unitest模块如何工作,引用该字典时应该有一些值。