Sun*_*ine 6 python automated-tests pytest python-3.x python-unittest
我有一个返回如下值的fixture:
import pytest
@pytest.yield_fixture(scope="module")
def oneTimeSetUp(browser):
print("Running one time setUp")
if browser == 'firefox':
driver = webdriver.Firefox()
print("Running tests on FF")
else:
driver = webdriver.Chrome()
print("Running tests on chrome")
yield driver
print("Running one time tearDown")
Run Code Online (Sandbox Code Playgroud)
此夹具从另一个夹具中获取浏览器值,该夹具正在读取命令行选项.
然后我有一个测试类,我有多个测试方法,他们都想使用相同的返回值驱动程序来进行测试.
import pytest
@pytest.mark.usefixtures("oneTimeSetUp")
class TestClassDemo():
def test_methodA(self):
# I would like to use the driver value here
# How could I do this?
# Something like this
self.driver.get("https://www.google.com")
self.driver.find_element(By.ID, "some id")
print("Running method A")
def test_methodB(self):
print("Running method B")
Run Code Online (Sandbox Code Playgroud)
使用self.driver失败并显示错误消息
self = <test_class_demo.TestClassDemo object at 0x102fb6c18>
def test_methodA(self):
> self.driver.get("https://www.google.com")
E AttributeError: 'TestClassDemo' object has no attribute 'driver'
Run Code Online (Sandbox Code Playgroud)
我知道我可以将fixture作为参数传递给我想要使用它的每个方法,但这不是最好的方法,因为我需要在每个方法中使用它,并且应该可以将它传递给类然后使用它在所有的测试方法中.
我可以使驱动程序对象可用于方法的最佳方法是什么?
编辑1:
像建议的那样在conftest.py中创建了夹具
@pytest.yield_fixture(scope="class") # <-- note class scope
def oneTimeSetUp(request, browser): # <-- note the additional `request` param
print("Running one time setUp")
if browser == 'firefox':
driver = webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(3)
print("Running tests on FF")
else:
driver = webdriver.Chrome()
print("Running tests on chrome")
## add `driver` attribute to the class under test -->
if request.cls is not None:
request.cls.driver = driver
## <--
yield driver
print("Running one time tearDown")
Run Code Online (Sandbox Code Playgroud)
我还有一个类,TestClassDemo中有需要的对象,我需要将相同的驱动程序实例传递给类.将其视为ABC类
class ABC():
def __init(self, driver):
self.driver = driver
def enterName(self):
# Do something with driver instance
Run Code Online (Sandbox Code Playgroud)
然后在TestClassDemo中
@pytest.mark.usefixtures("oneTimeSetUp", "setUp")
class TestClassDemo(unittest.TestCase):
# I need to create an object of class ABC, so that I can use it here
# abc = ABC(self.driver)
@pytest.fixture(scope="class", autouse=True)
def setup(self):
self.abc = ABC(self.driver)
# I tried this, but it's not working
# This error message shows up
# AttributeError: 'TestClassDemo' object has no attribute 'driver'
def setup_module(self):
self.abc = ABC(self.driver)
# This also does not work
# Error message -> AttributeError: 'TestClassDemo' object has no attribute 'abc'
def test_methodA(self):
self.driver.get("https://google.com")
self.abc.enterName("test")
print("Running method A")
def test_methodB(self):
self.abc.enterName("test")
print("Running method B")
Run Code Online (Sandbox Code Playgroud)
此abc对象也应该可用于其他test_方法.
所有这些类都在单独的模块中,我的意思是在单独的.py文件中说.
另外请在答案中解释什么是使用而不是yield驱动程序实例的最佳方法.
编辑2:
对于没有良率的这个例子,运行oneTimeTearDown的最佳方法是什么?在收益率之后,我正在运行tearDown步骤
@pytest.fixture(scope="class")
def oneTimeSetUp(request, browser):
print("Running one time setUp")
if browser == 'firefox':
driver = webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(3)
print("Running tests on FF")
else:
driver = webdriver.Chrome()
print("Running tests on chrome")
if request.cls is not None:
request.cls.driver = driver
Run Code Online (Sandbox Code Playgroud)
我也尝试使用UnitTest类,但是当我使用def setUpClass(cls)时,我无法使用test_方法中实例化的对象.所以我无法弄清楚如何实现这一目标.
我还想从命令行提供像浏览器这样的命令行参数,当我尝试使用unittest时,我不得不在每个类中编写命令行参数.我想只在一个地方提供它们,就像测试套件一样.所以在这里对我有所帮助.
我有一个关于stackoverflow的问题,但没有得到回复.你能看一下吗? Python unittest将参数传递给父测试类
谢谢
谢谢
py.text unittest集成文档中概述了一种技术,该技术可能对您有所帮助...使用内置request夹具。否则,如果不提供命名的夹具作为方法参数,我将无法知道访问夹具返回值的方法。
@pytest.yield_fixture(scope="class") # <-- note class scope
def oneTimeSetUp(request, browser): # <-- note the additional `request` param
print("Running one time setUp")
if browser == 'firefox':
driver = webdriver.Firefox()
print("Running tests on FF")
else:
driver = webdriver.Chrome()
print("Running tests on chrome")
## add `driver` attribute to the class under test -->
if request.cls is not None:
request.cls.driver = driver
## <--
yield driver
print("Running one time tearDown")
Run Code Online (Sandbox Code Playgroud)
现在,您可以driver像TestClassDemo在示例中一样(即self.driver应该工作)访问中的as class属性。
注意,您的灯具必须使用scope='class',否则request对象将不具有cls属性。
希望对您有所帮助!
更新
我还有一个类,在TestClassDemo中需要该对象,并且需要将相同的驱动程序实例传递给该类。认为它是ABC类
没有更多上下文就很难知道,但是在我看来,您可以ABC在实例化夹具中的driver... 的同时实例化对象oneTimeSetUp。例如 ...
@pytest.yield_fixture(scope="class")
def oneTimeSetUp(request, browser):
print("Running one time setUp")
if browser == 'firefox':
driver = webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(3)
print("Running tests on FF")
else:
driver = webdriver.Chrome()
print("Running tests on chrome")
if request.cls is not None:
request.cls.driver = driver
request.cls.abc = ABC(driver) # <-- here
yield driver
print("Running one time tearDown")
Run Code Online (Sandbox Code Playgroud)
但是,如果您只需要一个或两个测试类的ABC实例,就可以在类定义中使用固定装置...
@pytest.mark.usefixtures("oneTimeSetUp", "setUp")
class TestClassDemo(unittest.TestCase):
@pytest.fixture(autouse=True)
def build_abc(self, oneTimeSetUp): # <-- note the oneTimeSetup reference here
self.abc = ABC(self.driver)
def test_methodA(self):
self.driver.get("https://google.com")
self.abc.enterName("test")
print("Running method A")
def test_methodB(self):
self.abc.enterName("test")
print("Running method B")
Run Code Online (Sandbox Code Playgroud)
对于第二个示例,我不会特别满意。第三种选择是拥有另一个yield_fixture或类似的东西,它oneTimeSetUp与驱动程序已经包装好的ABC实例完全分开并返回。
哪种方式最适合您?不确定。您需要根据所使用的内容进行决策。
对于后代,应该适当指出pytest固定装置只是糖和一些魔术。如果发现它们很困难,则根本不需要使用它们。pytest很高兴执行香草单元测试TestCases。
另外,请在答案中说明什么是代替yield driver实例的最佳使用方法。
这就是我的想法...
@pytest.fixture(scope="class")
def oneTimeSetUp(request, browser):
print("Running one time setUp")
if browser == 'firefox':
driver = webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(3)
print("Running tests on FF")
else:
driver = webdriver.Chrome()
print("Running tests on chrome")
if request.cls is not None:
request.cls.driver = driver
Run Code Online (Sandbox Code Playgroud)
...请注意,这不会返回(或产生)驱动程序对象,这意味着将此固定装置作为函数/方法的命名参数提供不再有用,如果所有测试用例都是作为类编写(由您的示例建议)。
但是,如果要将夹具用作命名参数,则不要这样做。
| 归档时间: |
|
| 查看次数: |
11918 次 |
| 最近记录: |