自动化测试框架搭建-参数化-3
? ? ? ?在前面的設計中,已經實現了配置信息的分離,并且添加了log日志,接下來我們應該嘗試著進行數據分離,進行參數化了。修改file_reader1.py文件,添加ExcelReader類讀取xlrd,實現讀取excel內容的功能:
首先在工程framework下創建一個data的package,并在PC本地的data目錄下創建一個baidu.excel包含數據的表格。
加入了去excel功能的file_reader1.py的模塊如下:
#coding:utf-8 """ file_reader1.py:文件讀取。YamlReader讀取yaml文件,ExcelReader讀取excel。 """import yaml import os from xlrd import open_workbookclass YamReader():def __init__(self,yaml):if os.path.exists(yaml):self.yaml = yamlelse:raise IOError("文件不存在!")self._data = None@propertydef data(self):#如果是第一次調用data,讀取yaml文檔,否則直接返回之前保存的數據if not self._data:with open(self.yaml,'rb') as f:#load之后是一個generator,用list組織成列表self._data = list(yaml.safe_load_all(f))return self._dataclass SheetTypeError(Exception):passclass ExcelReader():"""讀取excel文件中的內容。返回list。 """def __init__(self,excel,sheet = 0,title_line = True):if os.path.exists(excel):self.excel = excelelse:raise IOError("The excel file does not exist!")self.sheet = sheetself.title_line = title_lineself._data = list()@propertydef data(self):if not self._data:workbook = open_workbook(self.excel)if type(self.sheet) not in [int ,str]:raise SheetTypeError("Please pass in <type int> or <type str>,not {0}".format(type(self.sheet)))elif type(self.sheet) == int:s = workbook.sheet_by_index(self.sheet)else:s = workbook.sheet_by_name(self.sheet)if self.title_line:#the first row is titletitle = s.row_values(0)for col in range(1,s.nrows):#依次遍歷其余的行,與首行組成dict,拼接到seld._data中self._data.append(dict(zip(title,s.row_values(col))))else:for col in range(0,s.nrows):#遍歷所有行,拼到s._data中self._data.append(s.row_values(col))return self._dataif __name__ == "__main__":here = os.path.dirname(os.path.dirname(__file__))config_path = os.path.join(here, 'config/config.yaml')#y = r"?F:\py_test\Framework\config\config.yaml"reader = YamReader(config_path)print (reader.data)#e = r"?F:/py_test/Framework/data/baidu.xlsx"excel_path = os.path.join(here,'data/baidu.xlsx')print excel_pathreader = ExcelReader(excel_path)print (reader.data)對于屬性定義采用類似C++中的私有方法,使用_data的形式,可參考_*、__*、__*__的區別,可以指定sheet,通過index或者name進行數據訪問,為了測試本模塊的功能,excel中的數據如下:
ExcelReader(excel,sheet =2) 或者? ExcelReader(excel,sheet = 'BaiduTest');此外設計了title_line標識位來判斷excel中是否標題行,如果有標題行,返回dict列表,如果無標題行,則返回list列表.
有標題行:print(ExcelReader(excel_path,title_line = True).data),則輸出為:
無標題行:print(ExcelReader(excel_path,title_line = False).data),則輸出為:
這里在excel中存儲的搜索數據為:
對于test_baidu4.py模塊,進行相應的修改:
#coding:utf-8"""test_baidu4.py 加入讀取excel表中數據的功能""" import os import time import unittest from selenium import webdriver from selenium.webdriver.common.by import By from Framework.utils.config import Config, DRIVER_PATH, DATA_PATH from Framework.utils.log import logger from Framework.utils.file_reader1 import ExcelReaderclass TestBaiDu(unittest.TestCase):driver = NoneURL = Config().get('URL')#excel = DATA_PATH + '/baidu.xlsx'excel = os.path.join(DATA_PATH,'baidu.xlsx')locator_kw = (By.ID, 'kw')locator_su = (By.ID, 'su')locator_result = (By.XPATH, '//div[contains(@class, "result")]/h3/a')def sub_setUp(self):self.driver = webdriver.Chrome(executable_path=DRIVER_PATH + '\chromedriver.exe')self.driver.get(self.URL)def sub_tearDown(self):self.driver.quit()################################################################################################def test_search(self):datas = ExcelReader(self.excel).dataprint datasfor d in datas:self.sub_setUp()print self.driverself.driver.find_element(*self.locator_kw).send_keys(d['search'])self.driver.find_element(*self.locator_su).click()time.sleep(1)#links = self.driver.find_element(*self.locator_result) #錯誤信息定位,TypeError:'WebElement object is not iterablelinks = self.driver.find_elements(*self.locator_result) #錯誤信息更正for link in links:logger.info(link.text)self.sub_tearDown()##############################################################################################if __name__ == '__main__':unittest.main(verbosity=2)Python 3的使用越來越多,而且3的unittest中帶有subTest,能夠通過子用例實現參數化。而用2的話需要unittest2或其他的庫來實現。如果是py3,將上面###之間的代碼替換如下就可以了,可以直接調用subTest()方法
def test_search(self):datas = ExcelReader(self.excel).datafor d in datas:with self.subTest(data=d):self.sub_setUp()self.driver.find_element(*self.locator_kw).send_keys(d['search'])self.driver.find_element(*self.locator_su).click()time.sleep(2)links = self.driver.find_elements(*self.locator_result)for link in links:logger.info(link.text)self.sub_tearDown()運行的時候,可以正常搜索selenium,但是沒有運行python selenium的搜索,提示:TypeError:'WebElement' object is not iterable:
? ? ? ?通過在日志打印的for循環加上打印進行定位,發現因為要搜索的是一組元素就是“selenium”和“python selenium”但是使用的元素定位方法是find_element,這里應該使用的是find_elements(),在上述test_baidu4.py中已經指出并進行了更正,即為:
#修改錯誤:TypeError:'WebElement' object is not iterable #links = self.driver.find_element(*self.locator_result) #錯誤信息定位,TypeError:'WebElement object is not iterable links = self.driver.find_elements(*self.locator_result) #錯誤信息更正為了便于理解其中的執行流程,在test_baidu4.py中加了打印信息,輸出結果:
這樣就實現了數據的分離,后面要搜索什么,只需要添加在excel中就可以了。
總結
以上是生活随笔為你收集整理的自动化测试框架搭建-参数化-3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自动化测试框架搭建-日志-2
- 下一篇: 自动化测试框架搭建-报告-4