如何在Python中使用decorator跨平台/浏览器运行测试?

如何在Python中使用decorator跨平台/浏览器运行测试?,python,selenium,parallel-processing,cross-platform,saucelabs,Python,Selenium,Parallel Processing,Cross Platform,Saucelabs,我有一个测试套件,如下所示: import unittest from selenium import webdriver SAUCE_USERNAME = 'xxx' SAUCE_ACCESS_KEY = 'xxx' sauce = SauceClient(SAUCE_USERNAME, SAUCE_ACCESS_KEY) browsers = [{"platform": "Mac OS X 10.9", "browserName": "chrome",

我有一个测试套件,如下所示:

import unittest
from selenium import webdriver

SAUCE_USERNAME = 'xxx'
SAUCE_ACCESS_KEY = 'xxx'
sauce = SauceClient(SAUCE_USERNAME, SAUCE_ACCESS_KEY)

browsers = [{"platform": "Mac OS X 10.9",
         "browserName": "chrome",
         "version": "31"},
        {"platform": "Windows 8.1",
         "browserName": "internet explorer",
         "version": "11"}]


def on_platforms(platforms):
    def decorator(base_class):
        module = sys.modules[base_class.__module__].__dict__
        for i, platform in enumerate(platforms):
            d = dict(base_class.__dict__)
            d['desired_capabilities'] = platform
            name = "%s_%s" % (base_class.__name__, i + 1)
            module[name] = new.classobj(name, (base_class,), d)
    return decorator

@on_platforms(browsers)
class MyTestSuite(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.desired_capabilities['name'] = cls.id()
        sauce_url = "http://%s:%s@ondemand.saucelabs.com:80/wd/hub"
        cls.driver = webdriver.Remote(
        desired_capabilities=cls.desired_capabilities,
        command_executor=sauce_url % (SAUCE_USERNAME,SAUCE_ACCESS_KEY))
        cls.driver.implicitly_wait(30)

    def test_1from_sauce(self):
        pass

    def test_2from_sauce(self):
        pass

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()

if __name__ == "__main__":
     unittest.main()
我的目标是在浏览器中为浏览器/平台运行test_1from_sauce和test_2from_sauce,并且我确实希望在setUpClass上设置的浏览器上连续执行这两项操作。为了进一步解释,我想打开一个浏览器并进行两个测试,然后退出该驱动程序并启动另一个驱动程序

现在,当我运行此代码时,出现以下错误: TypeError:必须使用SeleniumSuce_2实例作为第一个参数调用未绑定的方法setUpClass()(而不是获取任何内容)

我知道在类和子类声明中应该有一个修改,但我不知道我应该做什么,或者我应该更改什么部分

编辑:我省略了下面一行,效果很好:


cls.desired\u功能['name']=cls.id()

您在问题中显示的代码缺少对
sys
new
的导入。其次,在添加正确的导入后运行代码时,我遇到的错误不是您在问题中报告的错误,而是:

EE
======================================================================
ERROR: setUpClass (__main__.MyTestSuite_1)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests.py", line 33, in setUpClass
    cls.desired_capabilities['name'] = cls.id()
TypeError: unbound method id() must be called with MyTestSuite_1 instance as first argument (got nothing instead)
我省略了第二个
错误
,它与上面相同,只是它是针对
MyTestSuite_2
而不是
MyTestSuite_1
。问题很清楚。您调用
cls
id()
成员,但是
id()
实例方法而不是类方法,因此它需要类的实例,而不是类本身。我不确定您最终想要的是什么,但如果您将其用于
设置类
,则不再发生错误,并尝试连接:

@classmethod
def setUpClass(cls):
    cls.desired_capabilities['name'] = cls.__name__
    sauce_url = "http://%s:%s@ondemand.saucelabs.com:80/wd/hub"
    cls.driver = webdriver.Remote(
        desired_capabilities=cls.desired_capabilities,
        command_executor=sauce_url % (SAUCE_USERNAME, SAUCE_ACCESS_KEY))
    cls.driver.implicitly_wait(30)
唯一的修改是方法的第一行


顺便说一下,我不明白为什么要使用
new.classobj
。一方面,
new
模块已被弃用。其次,使用
类型
内置而不是
new.classobj
有效。

感谢@Louis给出的答案和您关于new.classobj的信息。