[英]How to run tests cross-platform/browser using decorator in Python?
I have a test suite as below: 我有一个测试套件,如下所示:
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()
My goal is to run test_1from_sauce and test_2from_sauce for browsers/platforms in browsers and ALSO I do want to do both of them in a row on the browser that is setup on setUpClass. 我的目标是为浏览器中的浏览器/平台运行test_1from_sauce和test_2from_sauce,而且我也想在setUpClass上设置的浏览器中连续执行这两个操作。 To explain more, I want to open a browser and do both tests then quit that driver and start another driver.
为了进一步说明,我想打开浏览器并进行两个测试,然后退出该驱动程序并启动另一个驱动程序。
Right now when I run this code, I get this error: TypeError: unbound method setUpClass() must be called with SeleniumSauce_2 instance as first argument (got nothing instead) 现在,当我运行此代码时,出现以下错误:TypeError:必须使用SeleniumSauce_2实例作为第一个参数调用未绑定方法setUpClass()。
I know there should be a modification in class and subclass declaration but I do not know what should I do or what part should I change. 我知道应该在类和子类声明中进行修改,但是我不知道应该做什么或应该更改什么部分。
EDITED: I omitted the following line and it worked fine: 编辑:我省略了以下行,它工作正常:
cls.desired_capabilities['name'] = cls.id()
The code you show in your question is missing the imports for sys
and new
. 您在问题中显示的代码缺少
sys
和new
的导入。 Secondly, the error I get when I run your code after adding the right imports is not what you report in your question but this: 其次,添加正确的导入后运行代码时出现的错误不是您在问题中报告的内容,而是:
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)
I've omitted a second ERROR
which is the same as above except that it is for MyTestSuite_2
rather than MyTestSuite_1
. 我省略了第二个
ERROR
,它与上面的相同,只是它是针对MyTestSuite_2
而不是MyTestSuite_1
。 The problem is pretty clear. 问题很明显。 You call the
id()
member of cls
but id()
is an instance method not a class method so it needs an instance of the class, not the class itself. 您调用了
cls
的id()
成员,但是id()
是一个实例方法而不是类方法,因此它需要类的实例,而不是类本身。 I'm not sure what it is you want in the end but if you use this for your setUpClass
, then the error no longer occurs and an attempt is made to connect: 我不确定最终想要什么,但是如果将其用于
setUpClass
,则不再发生错误,并尝试进行连接:
@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)
The only modification is the first line of the method. 唯一的修改是方法的第一行。
By the way, I don't get why you use new.classobj
. 顺便说一句,我不明白为什么要使用
new.classobj
。 For one thing, the new
module is deprecated. 一方面,不建议使用
new
模块。 Secondly, using the type
built-in rather than new.classobj
works. 其次,使用内置
type
而不是new.classobj
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.