使用 selenium 和 pytest 设置项目

Setting project with selenium and pytest

提问人:Biedrzu 提问时间:10/18/2023 更新时间:10/18/2023 访问量:77

问:

最近,我用 Selenium 和 Pytest 开始了一个新项目,我不确定设置驱动程序和项目总体结构的最佳方法是什么。

我已经在BaseClass中设置了驱动程序:

class BaseClass:
    service_obj = Service()
    chrome_options = Options()
    driver = webdriver.Chrome(service=service_obj, options=chrome_options)

页面对象模型以及测试自身继承自 BaseClass:

# Page Object class
class LoginPage(BaseClass):
    username_input = (By.ID, 'username-input')
    username_password = (By.ID, 'username-password')

    @classmethod
    def type_login_password(self, login, password):
        self.driver.find_element(LoginPage.username_input).send_keys(login)
        self.driver.find_element(LoginPage.username_password).send_keys(password)

    
# Test class
class TestLogin(BaseClass):
    def test_login(self):
        LoginPage.type_login_password('username', 'password')

我试图解决的问题是,有了上述解决方案,我在LoginPage中的所有方法都会@classmethods。这是正确的解决方案吗?我不明白为什么每次都必须在我的测试类或页面对象类中初始化驱动程序对象。

我知道我可以简单地删除类,但保留它们有助于更好地设置测试环境 - >具有不同作用域的pytest夹具

我尝试在不同的论坛或博客上寻找答案,但从我在大多数示例中发现的情况来看,人们只是在每个类中初始化新的驱动程序实例。

python selenium-webdriver 测试 pytest 夹具

评论


答:

0赞 Mahboob Nur 10/18/2023 #1

我在您的 BaseClass 中进行了一些修改。@pytest.fixture 装饰器允许您定义可重复使用的夹具以进行设置和拆卸。

import pytest
from selenium import webdriver

@pytest.fixture(scope="class")
def setup(request):
    service_obj = Service()
    chrome_options = Options()
    driver = webdriver.Chrome(service=service_obj, options=chrome_options)
    request.cls.driver = driver
    yield
    driver.quit()
 

您可以删除 ClassMethod 装饰器,并使用由安装夹具设置的 Self.Driver 实例变量。

class LoginPage:
    def __init__(self, driver):
        self.driver = driver
        self.username_input = (By.ID, 'username-input')
        self.username_password = (By.ID, 'username-password')

    def type_login_password(self, login, password):
        self.driver.find_element(*self.username_input).send_keys(login)
        self.driver.find_element(*self.username_password).send_keys(password)

class TestLogin:
    def test_login(self):
        page = LoginPage(self.driver)
        page.type_login_password('username', 'password')

希望它对你有用。

评论

0赞 Biedrzu 10/19/2023
嘿,谢谢你的回答!有了这个解决方案,我真的不喜欢当我输入self.driver时的事实。我没有收到 VSC 的建议。你知道有什么解决方案吗?当我想访问 conftest.py 文件中的另一个灯具中的驱动程序时,该怎么办?可能吗?
0赞 Michael Mintz 10/18/2023 #2

您可以尝试一个已经与页面对象模型组合在一起的框架:https://github.com/seleniumbase/SeleniumBaseseleniumpytest

下面是一个包含登录名和页面对象的脚本。使用 / 运行:pytestpython

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class LoginPage:
    def login_to_swag_labs(self, sb, username):
        sb.open("https://www.saucedemo.com")
        sb.type("#user-name", username)
        sb.type("#password", "secret_sauce")
        sb.click('input[type="submit"]')

class MyTests(BaseCase):
    def test_swag_labs_login(self):
        LoginPage().login_to_swag_labs(self, "standard_user")
        self.assert_element("div.inventory_list")
        self.assert_element('div:contains("Sauce Labs Backpack")')
        self.js_click("a#logout_sidebar_link")
        self.assert_element("div#login_button_container")

(无需使用 .许多有用的命令行选项,例如在不同测试之间重用浏览器会话。您甚至可以使用以下命令从 Chrome 更改默认浏览器:、、 等)@classmethod--rs--edge--firefox--safari

评论

0赞 Biedrzu 10/19/2023
感谢您的回答 Mintz!实际上,我已经考虑过SeleniumBase,但是在我目前工作的公司中,还有其他一些使用原始硒的项目,所以我宁愿坚持下去