· PageObjectUnittestddt数据驱动用例
· 执行日志、分布式执行
3、项目架构 4、浏览器Driver定义from common.readFile import ReadFilefrom common.logger import Loggerfrom selenium import webdriverlogger Logger()from selenium.webdriver import Remoteclass Browser(): def __init__(self): config ReadFile() self.browser config.readConfig("Browser", "browser") self.host config.readConfig("host","host") logger.info("You had select {} host {} browser.".format(self.host,self.browser)) def driver(self): """ 启动浏览器驱动 :return: 返回浏览器驱动URL """ try: # driver webdriver.Chrome() driver Remote(command_executorhttp:// self.host /wd/hub, desired_capabilities{ platform: ANY, browserName: self.browser, version: "", JavascriptEnabled: True } ) return driver except Exception as msg: print("驱动异常-> {0}".format(msg))
5、用例运行前后的环境准备工作import unittestfrom common.driver import Browserclass StartEnd(unittest.TestCase): def setUp(self): self.driver Browser().driver() self.driver.implicitly_wait(10) self.driver.maximize_window() def tearDown(self): self.driver.quit()
6、工具方法模块主要封装一些公共的方法如截图查找最新报告。
import timefrom selenium import webdriverimport os,syssys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))from config import settingdef inser_img(driver): # 指定截图存放的根目录路径 screen_dir setting.TEST_REPORT /imges/ rq time.strftime(%Y%m%d%H%M%S, time.localtime(time.time())) screen_name screen_dir rq .png driver.get_screenshot_as_file(screen_name) print(screenshot: screen_name)#查找最新的测试报告def latest_report(report_dir): lists os.listdir(report_dir) lists.sort(keylambda fn: os.path.getatime(report_dir \\ fn)) file os.path.join(report_dir, lists[-1]) return filedef latest_report_img(report_dir): lists os.listdir(report_dir) lists.sort(keylambda fn: os.path.getatime(report_dir \\ fn)) file os.path.join(report_dir, lists[-1]) return file
7、Pageobject页面对象封装基础页面类
import timefrom selenium import webdriverfrom selenium.common.exceptions import NoSuchElementExceptionfrom common.logger import Loggerfrom common.readFile import ReadFilelogger Logger()class BasePage(): "定义一个页面基类让所有页面都继承这个类封装一些常用的页面操作方法到这个类" def __init__(self, driver): self.driver driver config ReadFile() self.baseurl config.readConfig("BaseUrl", "url") def open_url(self, url): self.driver.get(self.baseurl url) # 退出浏览器 def quit_browser(self): self.driver.quit() # 浏览器前进操作 def forward(self): self.driver.forward() # 浏览器后退操作 def back(self): self.driver.back() # 隐式等待 def wait(self, seconds): self.driver.implicitly_wait(seconds) # 查找元素 def find_element(self, selector): selector_by selector[find_type] selector_value selector[element_info] try: if selector_by id: el self.driver.find_element_by_id(selector_value) elif selector_by "n" or selector_by name: el self.driver.find_element_by_name(selector_value) elif selector_by cs or selector_by css_selector: el self.driver.find_element_by_css_selector(selector_value) elif selector_by cn or selector_by classname: el self.driver.find_element_by_class_name(selector_value) elif selector_by "lt" or selector_by link_text: el self.driver.find_element_by_link_text(selector_value) elif selector_by "plt" or selector_by partial_link_text: el self.driver.find_element_by_partial_link_text(selector_value) elif selector_by "tn" or selector_by tag_name: el self.driver.find_element_by_tag_name(selector_value) elif selector_by "x" or selector_by xpath: el self.driver.find_element_by_xpath(selector_value) elif selector_by "ss" or selector_by selector_selector: el self.driver.find_element_by_css_selector(selector_value) else: raise NameError("Please enter a valid type of targeting elements.") except NoSuchElementException : logger.error("{0}页面中未能找到{1}元素".format(self, selector_value)) return el # 输入 def input(self, selector, text): el self.find_element(selector) try: el.clear() el.send_keys(text) logger.info("Had type \ %s \ in inputBox" % text) except NameError as e: logger.error("Failed to type in input box with %s" % e) # 点击 def click(self, selector): el self.find_element(selector) try: logger.info("The element \ %s \ was clicked." % el.text) el.click() except NameError as e: logger.error("Failed to click the element with %s" % e) staticmethod def sleep(seconds): time.sleep(seconds) logger.info("Sleep for %d seconds" % seconds) def get_text(self,selector): el self.find_element(selector) try: return el.text except NameError as e: logger.error("Failed to text the element with %s" % e) def switch_frame(self, selector): """ 多表单嵌套切换 :param loc: 传元素的属性值 :return: 定位到的元素 """ try: el self.find_element(selector) return self.driver.switch_to_frame(el) except NoSuchElementException as e: logger.error("查找iframe异常-> {0}".format(e)) def switch_windows(self, selector): """ 多窗口切换 :param loc: :return: """ try: el self.find_element(selector) return self.driver.switch_to_window(el) except NoSuchElementException as e: logger.error("查找窗口句柄handle异常-> {0}".format(e)) def switch_alert(self): """ 警告框处理 :return: """ try: return self.driver.switch_to_alert() except NoSuchElementException as e: logger.error("查找alert弹出框异常-> {0}".format(e))
LoginPage.py —— CNDS登录页面
from pageObject.basePage import *from selenium import webdriverfrom common.readFile import ReadFilefrom config import settinglogin_el ReadFile().readYaml(setting.TEST_Element_YAML / login.yaml)data ReadFile().readYaml(setting.TEST_DATA_YAML / login_data.yaml)class CndsPage(BasePage): 登录页面 url /login # 定位器通过元素属性定位元素对象 #选择账号密码登录 chanlelogin_loc login_el[testcase][0] # 账号输入框 username_loc login_el[testcase][1] # 密码输入框 pwd_loc login_el[testcase][2] # 单击登录 login_accout_loc login_el[testcase][3] def accout_login(self,accout,passwd): self.open_url(self.url) self.click(self.chanlelogin_loc) self.input(self.username_loc,accout) self.input(self.pwd_loc,passwd) self.click(self.login_accout_loc) # 定位器通过元素属性定位检查项元素对象 user_login_success_loc login_el[check][0] accout_id_loc login_el[check][1] accout_pawd_error_loc login_el[check][2] # 账号或密码错误提示 def accout_passwd_error(self): return self.get_text(self.accout_pawd_error_loc) # 登录成功跳转到个人资料页获取用户名 def get_account(self): self.click(self.user_login_success_loc) time.sleep(2) def user_login_success(self): return self.find_element(self.accout_id_loc).text
8、组织测试用例· 用户名密码正确点击登录
· 用户名正确密码错误点击登录
import unittestfrom common import function,myUnit,readFilefrom pageObject.loginPage import CndsPagefrom time import sleepfrom common.logger import Loggerfrom config import settingimport ddtlog Logger()testData readFile.ReadFile().readYaml(setting.TEST_DATA_YAML / login_data.yaml)ddt.ddtclass LoginTest(myUnit.StartEnd): # unittest.skip(skip this case) """CNDS登录测试""" def user_login_verify(self,account,passwd): """ 用户登录 :param :account 账号 :param passwd: 密码 :return: """ CndsPage(self.driver).accout_login(account,passwd) ddt.data(*testData) def test_login_normal(self,datayaml): log.info("test_login1_normal is start run...") self.user_login_verify(datayaml[data][accout],datayaml[data][passwd]) sleep(3) #断言与截屏 po CndsPage(self.driver) if datayaml[screenshot] login_success: po.get_account() function.inser_img(self.driver) self.assertEqual(po.user_login_success(), datayaml[check][0], "登录成功返回实际结果是->: {0}".format(po.user_login_success())) else: function.inser_img(self.driver) self.assertEqual(po.accout_passwd_error(), datayaml[check][0],"登录失败返回实际结果是->: {0}".format(po.accout_passwd_error())) print("test_login1_normal is test end!")
9、 执行测试用例import unittestfrom common.function import latest_reportfrom common.sendMail import *from config import settingfrom thridLib.HTMLTestRunner import HTMLTestRunnerimport timeimport os,syssys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))report_dir setting.TEST_REPORT /report/def add_case(test_pathsetting.TEST_DIR): discover unittest.defaultTestLoader.discover(test_path, pattern"test*.py") return discoverdef run_case(all_case,result_pathreport_dir): print("start run testcase...") now time.strftime("%Y-%m-%d %H_%M_%S") report_name result_path / now result.html print("start write report...") #HTMLTestRunner测试报告 with open(report_name, wb) as f: runner HTMLTestRunner(streamf, title测试报告, description用例执行情况) # 定义测试报告 runner.run(all_case) # 执行测试用例 f.close() print("find latest report...") # 查找最新的测试报告 report latest_report(result_path) # 邮件发送报告 print("send email report...") send_mail(report) print("test end!")if __name__ __main__: cases add_case() run_case(cases)
学习安排上最后感谢每一个认真阅读我文章的人看着粉丝一路的上涨和关注礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走
这些资料对于想进阶【自动化测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你凡事要趁早特别是技术行业一定要提升技术功底。