数据驱动测试。使用 Selenium Python 从 .json 或 .yaml 文件读取参数

Data driven tests. reading parameters from a .json or .yaml file using Selenium Python

我使用 Selenium 和 Python 创建了一个框架。 到目前为止,我的数据驱动框架由 2 个文件组成: 第一个文件- Setup.py 包含 class Actions() 包含我将使用的所有可能的功能 在我的框架中,例如:

def __init__(): 
def setup():
def tearDown():
def click():
def sendKeys():

我的 clicksendKeys 函数至少有 2 个参数。 他们采用第一个参数,例如我们 :id_for_elementxp_for_element,或 css_for_element,切词直到 他们得到第一个两个字符并通过其中一个找到元素 id、xp 或任何其他方式。然后他们使用第二个参数来 指定一个元素的值,第三个参数指定 send_keys() 函数的值。所有这些功能 现在正在工作,但到目前为止,我的测试文件中的值是硬编码的。

setup.py file:

from   selenium import webdriver
from   selenium.webdriver.common.by import By
from   selenium.webdriver.common.keys import Keys
from   selenium.webdriver.support.ui import Select
from   selenium.common.exceptions import NoSuchElementException
from   selenium.common.exceptions import NoAlertPresentException

class Actions(object):

    def __init__(self,driver=None):
        if driver != None:
            self.driver = driver

    def setUp(self, browserName):
        if browserName == 'Chrome':
            self.driver = webdriver.Chrome()
            self.driver.delete_all_cookies()
            self.driver.maximize_window()
        elif browserName == 'Safari':
            self.driver = webdriver.Safari()
            self.driver.delete_all_cookies()
            self.driver.maximize_window()
        elif browserName == 'Firefox':
            self.driver = webdriver.Firefox()
            self.driver.delete_all_cookies()
            self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self, browserName):
        self.driver.quit()

    def webPage(self):
        self.driver.get('https://www.yahoo.com')

    def click(self, elemLocator, elemValue):
        elp = elemLocator
        flp = slice(0,2)
        if elp[flp] == 'id':#return by ID
            try:
                self.driver.find_element_by_id(elemValue).click()
            except:
                pass
        elif elp[flp] == 'xp':#return by XPATH
            try:
                self.driver.find_element_by_xpath(elemValue).click()
            except:
                pass


    def sendKeys(self, elemLocator, elemValue, messageValue):
        elp = elemLocator
        flp = slice(0,2)
        if elp[flp] == 'id':#return by ID
            try:
                self.driver.find_element_by_id(elemValue).click()
                self.driver.find_element_by_id(elemValue).clear()
                self.driver.find_element_by_id(elemValue).send_keys(messageValue)
            except:
                pass

        elif elp[flp] == 'xp':#return by XPATH
            try:
                self.driver.find_element_by_xpath(elemValue).click()
                self.driver.find_element_by_xpath(elemValue).clear()
                self.driver.find_element_by_xpath(elemValue).send_keys(messageValue)
            except:
                pass

#test.py file

    from Setup import Actions

class test_case_1: #find element by id

    action = Actions(object)
    action.setUp('Chrome')
    action.webPage()
    action.click('id_of_yahoo_logo', 'uh-logo')
    action.tearDown('Chrome')


class test_case_2: #find element by xpath

    action = Actions(object)
    action.setUp('Chrome')
    action.webPage()
    action.click('xp_of signIn_button', '//*[@id="uh-signin"]')
    action.tearDown('Chrome')

class test_case_3: #login to email

    action = Actions(object)
    action.setUp('Chrome')
    action.webPage()
    action.click('xp_of signIn_button', '//*[@id="uh-signin"]')
    action.sendKeys('id_username_login_inp_field','login-username','deniska')
    action.click('id_of submit_button', 'login-signin')
    action.tearDown('Chrome')

相反,我试图从另一个传递参数值 数据驱动测试最佳实践所描述的文件 框架。我的下一步是创建一个 data.json 文件 我将在下面使用映射出 DOM 的所有元素 格式:"id_login_button":"some id value", "xp_input_field":"some xp 值”等。请有人帮我弄清楚 如何实现这个技术?

如果您想使用 json 作为您的 uiRepo,这是简单的方法。

sample.json:

{
    "id_of_yahoo_logo":"uh-logo",
    "xp_of_signIn_button":"//*[@id='uh-signin']",
    "id_username_login_inp_field":"New York",
    "id_of_submit_button":"login-signin"
}

test.py

# you have to just specify the name as shown below
action.click('xp_of_signIn_button)

Actions.py中的读取值:

import json

#parse json
with open('sample.json') as f:
    uiRepo = json.load(f)

# update the generic methods to get the property form json
print(uiRepo['id_of_yahoo_logo'])

编辑1:setup.pyUn-Tested更新

from   selenium import webdriver
from   selenium.webdriver.common.by import By
from   selenium.webdriver.common.keys import Keys
from   selenium.webdriver.support.ui import Select
from   selenium.common.exceptions import NoSuchElementException
from   selenium.common.exceptions import NoAlertPresentException
import json

class Actions(object):
    # initialize uiRepo
    uiRepo = None
    def __init__(self,driver=None):
        if driver != None:
            self.driver = driver
            # load the uiRepo from json when you init the driver
            with open('sample.json') as repo:
                uiRepo = json.load(repo)

    def setUp(self, browserName):
        browserName = browserName.lower()
        if browserName == 'chrome':
            self.driver = webdriver.Chrome()
        elif browserName == 'safari':
            self.driver = webdriver.Safari()
        elif browserName == 'firefox':
            self.driver = webdriver.Firefox()
        self.driver.delete_all_cookies() #< === moved this line
        self.driver.maximize_window() #< === moved this line
        self.driver.implicitly_wait(30)

    def tearDown(self): #< === Removed browser here as you don't need browser name while closing it.
        self.driver.quit()

    def webPage(self,url): #< === Added url as param, rather hard code
        self.driver.get(url)

    # new method to get the element based on the jsonKey
    def getElement(self, jsonKey):
        locatorStrategy = jsonKey[:2]  # <=== getting first 2 chars to figure out if it's id/xp
        locator = uiRepo[jsonKey]  # < == getting value from json
        ele = None
        try:
            if locatorStrategy == 'id':  # return by ID
                ele =  self.driver.find_element_by_id(locator).click()  # <=== using the locator got from json
            elif locatorStrategy == 'xp':  # return by XPATH
                ele =  self.driver.find_element_by_xpath(locator).click()
        except:
            pass
        # if you want you can add additional logic something like highlighting the element
        return ele

    def click(self, jsonKey): # < ==== updated method to accept only jsonElementName (Removed the element value param)
        ele = self.findElement(jsonKey)
        ele.click()