如何在Selenium/Python中的参数化测试中从一个对象中选择一个项目,其中select方法在一个页面对象中?

zz2j4svz  于 5个月前  发布在  Python
关注(0)|答案(1)|浏览(71)

我的测试会遍历一个数组中的每一个值。在应用程序中,用户选择一个值,单击一个按钮将该值乘以它本身,然后应用程序显示计算结果。测试会验证计算结果是否与它应该是的数字相匹配。
版本:pytest:7.4.4 selenium:4.16.0 python:3.12
下面是我的test_math.py:

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from page_objects.app_page import AppPage

class TestMathApp:

    @pytest.mark.parametrize("input_value, expected_value",
                             [("1", "1"), ("2", "4"), ("3", "9"), ("4", "16"), ("5", "25"), ("6", "36"), ("7", "49"),
                              ("8", "64"), ("9", "81"), ("10", "100")])
    def test_nums_to_endpoint_1(self, driver, input_value, expected_value):
        app_page = AppPage(driver)
        app_page.open()
        app_page.select_value(input_value)
        app_page.click_endpoint_1()
        assert app_page.result == expected_value

字符串
下面是我的页面对象app_page.py:

from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.support.select import Select

from page_objects.base_page import BasePage

class AppPage(BasePage):
    __url = "http://localhost:3000/"
    __header = (By.TAG_NAME, "h1")
    __instruction = (By.TAG_NAME, "h2")
    __dropdown = (By.TAG_NAME, "select")
    __endpoint_1_button = (By.XPATH, "//button[contains(text(),'Send to Endpoint 1')]")
    __endpoint_2_button = (By.XPATH, "//button[contains(text(),'Send to Endpoint 2')]")
    __response_text = (By.TAG_NAME, "span")
    __result = (By.TAG_NAME, "label")

    def __init__(self, driver: webdriver):
        super().__init__(driver)

    def open(self):
        super()._open_url(self.__url)

    def click_endpoint_1(self):
        super()._click(self.__endpoint_1_button)

    def select_value(self, input_value):  # will have to unravel this
        super()._wait_until_element_is_visible(self.__dropdown)
        Select(self._driver.find_element(self.__dropdown)).select_by_value(input_value)

    @property
    def result(self) -> str:
        return super()._get_text(self.__result)


我的base_page.py:

from selenium import webdriver # may not need, idk
from selenium.common import NoSuchElementException
from selenium.webdriver.remote.webelement import WebElement # see if I don't need this. it messes with select_by_value and WebElement below is being weird anyway.
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

class BasePage:
    def __init__(self, driver: webdriver):
        self._driver = driver

    def _find(self, locator: tuple) -> WebElement: # think I need to add return?
        return self._driver.find_element(*locator)

    def _wait_until_element_is_visible(self, locator, time: int = 10):
        wait = WebDriverWait(self._driver, 10)
        wait.until(ec.visibility_of_element_located(locator))

    def _open_url(self, url: str):
        self._driver.get(url)  # does this need a wait?

    def _get_text(self, locator: tuple,  time: int = 10) -> str:
        self._wait_until_element_is_visible(locator, time)
        return self._find(locator).text

    def _click(self, locator: tuple, time: int = 10):
        self._wait_until_element_is_visible(locator, time)
        self._find(locator).click()


下面是控制台中的显示器:

<select>
    <option value="">Select</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
</select>


当我忽略页面对象模型来实际选择下面类似于JavaScript的项目时,测试通过了。我验证了结果是正确的,这取决于输入(例如,当输入为3时,结果为9):

def test_nums_to_endpoint_1(self, driver):
        app_page = AppPage(driver)
        app_page.open()
        dropdown_locator = Select(driver.find_element(By.TAG_NAME, "select"))
        dropdown_locator.select_by_value("3")
        app_page.click_endpoint_1()
        assert app_page.result == "9", print("Endpoint 1 should have returned '" + str(expected_value) + "' for '" + str(input_value) + "' but returned '" + str(app_page.result) + "'")


我在测试中一直在这一行得到错误selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: 'using' must be a string
app_page.select_value(input_value)
.当尝试将参数化测试转换为在页面对象模型中工作时。
我的select_value方法有什么问题吗?它看起来像我有一个字符串,但在某个时候沿着它看起来像我的元组的内容不再是一个字符串?

5ssjco0h

5ssjco0h1#

要解决这个问题,您应该使用BasePage中的_find方法,而不是直接在AppPage中的驱动程序上调用find_element。下面是修改后的select_value方法:

def select_value(self, input_value):
    super()._wait_until_element_is_visible(self.__dropdown)
    dropdown_element = self._find(self.__dropdown)
    Select(dropdown_element).select_by_value(input_value)

字符串
base_page.py缺少_click()定义,修复如下:

def _click(self, locator):
        element = self._driver.find_element(*locator)
        element.click()

相关问题