【问题标题】:Pytest - yield inside for works only the first way aroundPytest - yield inside for 仅适用于第一种方式
【发布时间】:2021-05-29 08:54:50
【问题描述】:

我试图让相同的测试在不同的浏览器中运行。每个浏览器都可以完美运行(["Chrome"] 或 ["Firefox"]),但是如果 supportedBrowsers 数组接收两个元素,则在第二次迭代中 yield 根本不会做任何事情,执行不会转到测试和夹具的其余部分都没有,浏览器站在那里打开。我错过了什么?

@pytest.fixture(scope='module')
def driver():
    url = "http://localhost:1234/"
    supportedBrowsers = ["Chrome", "Firefox"]
    for x in supportedBrowsers:
        if x == "Firefox":
            option = webdriver.firefox.options.Options()    
            driverObj = webdriver.Firefox(executable_path=GeckoDriverManager().install())
        elif x == "Chrome":
            option = webdriver.chrome.options.Options()
            driverObj = webdriver.Chrome(ChromeDriverManager().install())
        option.headless = True
        driverObj.implicitly_wait(10) # seconds
        driverObj.get(url)
        yield driverObj
        driverObj.quit()

【问题讨论】:

标签: python pytest yield


【解决方案1】:

当您使用 yield 时,有必要在函数上显式调用 next 以便前进到循环的下一次迭代。这就是产量的工作原理。喜欢

@pytest.fixture(scope='module')
def driver():
    url = "http://localhost:1234/"
    supportedBrowsers = ["Chrome", "Firefox"]
    for x in supportedBrowsers:
        if x == "Firefox":
            option = webdriver.firefox.options.Options()    
            driverObj = webdriver.Firefox(executable_path=GeckoDriverManager().install())
        elif x == "Chrome":
            option = webdriver.chrome.options.Options()
            driverObj = webdriver.Chrome(ChromeDriverManager().install())
        option.headless = True
        driverObj.implicitly_wait(10) # seconds
        driverObj.get(url)
        yield driverObj 
        driverObj.quit()
d=driver() 
next(d)  # this is when the function will actually goto yield and #stop there
next(d) # next iteration of loop. 
# you have call it as many times as you have browsers 

你也可以使用

for driver in driver():
    pass # automatically call next

【讨论】:

    【解决方案2】:

    这就是 yield fixtures 在 pytest 中的工作方式。第一个yield 相当于return 语句,允许轻松设置/拆卸。以下产量被忽略。

    我能想到的最简单的让它工作的方法是返厂。

    @pytest.fixture(scope='module')
    def drivers():
        def inner():
            # your previous fixture body with multiple yields goes here
        return inner
    

    现在你可以像这样使用它了:

    def test_xyz(drivers):
        for driver in drivers():
            # driver is Chrome or Firefox
    

    您也可以尝试使用parametrized fixture。这将使您的夹具看起来和行为像单个驱动程序,但将使用它运行每个测试两次(使用 Chrome 和 Firefox 驱动程序)。

    @pytest.fixture(scope='module', browsers=["Chrome", "Firefox"])
    def driver(request):
        # here goes body of your fixture without the for loop
        # request.param holds the browser value
    

    【讨论】:

    • 我选择了参数化夹具,它工作得非常好。谢谢!
    • 我很高兴它有帮助。您可以将其标记为已接受的答案并投票吗?
    猜你喜欢
    • 2013-01-28
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 2010-11-07
    • 2018-09-08
    • 2016-02-03
    • 2015-08-09
    相关资源
    最近更新 更多