简体   繁体   English

在订购参数化测试时访问具有类范围的 pytest 夹具参数

[英]Access pytest fixture params with class scope while ordering parametrized tests

在此处输入图片说明 For my selenium testing using pytest, I have below logic in the conftest.py file对于我使用 pytest 的硒测试,我在 conftest.py 文件中有以下逻辑

    import pytest
    from selenium import webdriver
    from webdriver_manager.chrome import ChromeDriverManager
    from webdriver_manager.firefox import GeckoDriverManager
    
    @pytest.fixture(params=["Chrome","Firefox"],scope='class')
    def oneTimeSetup1(request):
        if request.param == "Chrome":
            driver = webdriver.Chrome(ChromeDriverManager().install())
        if request.param == "Firefox":
            driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
    
        driver.implicitly_wait(5)
        driver.maximize_window()
        driver.get("https://courses.letskodeit.com/practice")
    
        if request.cls is not None:
            request.cls.driver = driver
        print("the velue of param is " + request.param)

    
        yield driver
        driver.quit()

my test structure is我的测试结构是

dir tests
--conftest.py
--test_one.py
----TestClassOne
------test_one
------test_two

when I collect the test, I can see below当我收集测试时,我可以看到下面

<Package tests>
  <Module test_one.py>
    <Class TestClassOne>
        <Function test_one[Chrome]>
        <Function test_one[Firefox]>
        <Function test_two[Chrome]>
        <Function test_two[Firefox]>

Since the scope of oneTimeSetup1 fixture is class, I am not sure why each test function is running with new browser session.由于 oneTimeSetup1 夹具的范围是类,我不确定为什么每个测试函数都在新的浏览器会话中运行。

Can we have a single Chrome browser session that will execute both my test_one & test_two and then the same for firefox.我们可以有一个单独的 Chrome 浏览器会话来执行我的 test_one 和 test_two ,然后对 firefox 执行相同的会话。

import pytest
from pages.page1 import Page1


@pytest.mark.usefixtures("oneTimeSetup1")
class TestClassOne():

    @pytest.fixture(autouse=True)
    def classObject(self):
        self.page = Page1(self.driver)

    @pytest.mark.run(order=1)
    def test_one(self):
        self.page.methodA()
        print("This is Test One")

    @pytest.mark.run(order=2)
    def test_two(self):
        self.page.methodC()
        print("This is Test Two")

As mentioned in the comments, the problem comes from the ordering via the pytest-ordering plugin.正如评论中提到的,问题来自通过pytest-ordering插件pytest-ordering This is actually expected behavior (and not a bug, as I wrote initially), because the tests are explicitely ordered, and this ordering is done after any initial ordering due to the fixture usage.这实际上是预期的行为(而不是错误,正如我最初写的那样),因为测试是明确排序的,并且由于夹具的使用,这种排序是在任何初始排序之后完成的。

There is a possibility to change this behavior, if using pytest-order (a fork of pytest-ordering , which is no longer maintained) with the option --indulgent-ordering .如果将pytest-orderpytest-ordering 的一个分支,不再维护)与选项--indulgent-ordering一起使用,则有可能改变这种行为。 This changes the sequence of the ordering, so that the tests are first ordered by the plugin, and afterwards by the fixture.这改变了排序的顺序,因此测试首先由插件排序,然后由夹具排序。 Note that you have to change the order marker from run to order in this case:请注意,您必须从顺序标记改变runorder在这种情况下:

...
    @pytest.mark.run(order=2)
    def test_one(self):
        self.page.methodA()
        print("This is Test One")

    @pytest.mark.order(1)
    def test_two(self):
        self.page.methodC()
        print("This is Test Two")

(I changed the order to show that the ordering has any effect). (我更改了顺序以显示排序有任何影响)。 If run this without an option, you will get (as seen in the original question):如果在没有选项的情况下运行它,您将得到(如原始问题所示):

$ python -m pytest --collect-only
<Package tests>
  <Module test_one.py>
    <Class TestClassOne>
        <Function test_two[Chrome]>
        <Function test_two[Firefox]>
        <Function test_one[Chrome]>
        <Function test_one[Firefox]>

With the --indulgent-ordering option, you get instead:使用--indulgent-ordering选项,您会得到:

$ python -m pytest --collect-only --indulgent-ordering
<Package tests>
  <Module test_one.py>
    <Class TestClassOne>
        <Function test_two[Chrome]>
        <Function test_one[Chrome]>
        <Function test_two[Firefox]>
        <Function test_one[Firefox]>

which makes it possible for the fixture to properly work as a class-scoped fixture.这使得夹具可以作为类范围的夹具正常工作。

As usually, you can add the option to your pytest.ini if you want it to be effective for all tests:通常,如果您希望它对所有测试都有效,您可以将选项添加到pytest.ini

[pytest]
addopts = --indulgent-ordering

Disclaimer :免责声明
I'm the author of pytest-order .我是pytest-order的作者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM